专栏文章

题解:P12782 [ICPC 2024 Yokohama R] E-Circuit Is Now on Sale!

P12782题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@minq8zsf
此快照首次捕获于
2025/12/02 06:35
3 个月前
此快照最后确认于
2025/12/02 06:35
3 个月前
查看原文

题目大意

  • 数字(0 到 9):直接返回数字。
  • 连接器(#):一个输入,一个输出,直接传递值。
  • 运算符(+,-,*,/):对两个输入进行运算并输出结果。
  • 打印机(P):显示最终结果。
所有元件通过相邻连接形成一棵以打印机为根的树,我们需要计算这棵表达式树的值。

解决方法

暴力dfs即可,具体细节搬到代码里讲。

代码实现

CPP
#include<bits/stdc++.h>
//#pragma GCC optimize("2","Ofast","inline")
#define int long long//不开long long见祖宗
using namespace std;
int n,m;
vector<string>s;//存储字符数据
vector<vector<bool>>v;//标记数组
int dx[]={-1,0,1,0},dy[]={0,1,0,-1};//方向数组
//判断位置(x,y)是否有效
bool f(int x,int y){
	return x>=0&&x<n&&y>=0&&y<m&&s[x][y]!='.';
}
//(xx,yy)为父节点
int dfs(int x,int y,int xx,int yy){
	v[x][y]=true;
	char c=s[x][y];
	if(isdigit(c))return c-'0';//如果是数字,直接返回对应的数值
	if(c=='#'){//连接器
		for(int d=0;d<4;d++){
			int nx=x+dx[d],ny=y+dy[d];
			if(f(nx,ny)&&!(nx==xx&&ny==yy)){//注意不能是父节点
				return dfs(nx,ny,x,y);
			}
		}
	}
	if(c=='+'||c=='-'||c=='*'||c=='/'){//运算符
		vector<int>q;//存储计算结果
		for(int d=0;d<4;d++){
			int nx=x+dx[d],ny=y+dy[d];
			if(f(nx,ny)&&!(nx==xx&&ny==yy)){
				q.push_back(dfs(nx,ny,x,y));//计算子节点值并加入数组
			}
		}
		int a=q[0],b=q[1];//两个子节点的计算结果
		if(c=='+')return a+b;
		if(c=='-')return max(a,b)-min(a,b);//大数减小数
		if(c=='*')return a*b;
		return max(a,b)/min(a,b);//大数除以小数
	}
	
	if(c=='P'){//打印机
		for(int d=0;d<4;d++){
			int nx=x+dx[d],ny=y+dy[d];
			if(f(nx,ny)){
				return dfs(nx,ny,x,y);
			}
		}
	}
}
signed main(){
	cin>>n>>m;
	s.resize(n+1);
	v.assign(n+1,vector<bool>(m+1,false));
	for(int i=0;i<n;i++){
		cin>>s[i];
	}
//找打印机
	int px=-1,py=-1;
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			if(s[i][j]=='P'){
				px=i,py=j;break;
			}
		}
	}
	cout<<dfs(px,py,-1,-1);//从打印机开始dfs
	return 0;
}
整体还是比较简单的,但比较考验代码实现能力。
时间复杂度:O(n×m)O(n\times m)

评论

0 条评论,欢迎与作者交流。

正在加载评论...