题解:SP2053 CERC07K - Key Task

思路

显然对于一个地图,求最短路,要用 bfs。

根据本题的限制条件,模拟即可。

可以使用 77 个队列,分别记录横坐标、纵坐标、有无四种颜色的钥匙,步数。

代码细节比较多,具体看代码吧。

代码

#include<bits/stdc++.h>
using namespace std;
queue<int>q1,q2,q3,q4,q5,q6,q7;
int n,m,s,t,vis[105][105][2][2][2][2];
char ch[105][105];
const int dx[5]={0,1,-1,0,0};
const int dy[5]={0,0,0,1,-1};
void popp(){
	q1.pop();
	q2.pop();
	q3.pop();
	q4.pop();
	q5.pop();
	q6.pop();
	q7.pop();
}
/*
用了 7 个队列:
q1 记录横坐标;
q2 记录纵坐标;
q3 记录有无蓝钥匙;
q4 记录有无黄钥匙;
q5 记录有无红钥匙;
q6 记录有无绿钥匙;
q7 记录步数。
*/
void bfs(int x,int y){
	while(!q1.empty())popp();
    //因为我们上一次找到了答案直接退出,所以队列中可能会有没有被遍历到的元素残留,要把它们去掉。
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			for(int k=0;k<=1;k++){
				for(int l=0;l<=1;l++){
					for(int p=0;p<=1;p++){
						for(int q=0;q<=1;q++){
							vis[i][j][k][l][p][q]=0;
						}
					}
				}
			}
		}
	}
   //六维 vis 数组,记录坐标及四种颜色有无。
	q1.push(x);
	q2.push(y);
	q3.push(0);
	q4.push(0);
	q5.push(0);
	q6.push(0);
	q7.push(0);
	int fb,fy,fr,fg,step;
	while(!q1.empty()){
		x=q1.front();
		y=q2.front();
		fb=q3.front();
		fy=q4.front();
		fr=q5.front();
		fg=q6.front();
		step=q7.front();
		popp();
		if(ch[x][y]=='X'){
			cout<<"Escape possible in "<<step<<" steps.\n";
			return;
		}
		if(ch[x][y]=='R'&&(!fr))continue;
		if(ch[x][y]=='G'&&(!fg))continue;
		if(ch[x][y]=='B'&&(!fb))continue;
		if(ch[x][y]=='Y'&&(!fy))continue;
		if(vis[x][y][fb][fy][fr][fg])continue;//判断条件,退出
		vis[x][y][fb][fy][fr][fg]=1;
		if(ch[x][y]=='r')fr=1;
		if(ch[x][y]=='g')fg=1;
		if(ch[x][y]=='b')fb=1;
		if(ch[x][y]=='y')fy=1;//判断钥匙
		for(int i=1;i<=4;i++){
			int nx=x+dx[i],ny=y+dy[i];
			if(nx<=0||nx>n||ny<=0||ny>m)continue;
			if(ch[nx][ny]=='#')continue;
			q1.push(nx);
			q2.push(ny);
			q3.push(fb);
			q4.push(fy);
			q5.push(fr);
			q6.push(fg);
			q7.push(step+1);
		}
	}
	cout<<"The poor student is trapped!\n";
	return;
}
int main(){
	while(cin>>n>>m){
		if(n==0&&m==0)break;
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				cin>>ch[i][j];
				if(ch[i][j]=='*'){
					s=i;
					t=j;
				}
			}
		}
		bfs(s,t);
	}
	return 0;
}

复杂度

最多会有 16×n×m16\times n\times m 个状态,所以时间复杂度是 O(n×m)\operatorname{O}(n\times m) 的。

posted @   Weslie_qwq  阅读(2)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示