【DFS】nyoj 82 迷宫寻宝(一)

本文介绍了一种使用深度优先搜索(DFS)算法解决迷宫问题的方法,包括算法的实现过程、关键步骤和代码解析。通过遍历迷宫地图,寻找从起点到终点的路径,特别关注在遇到新钥匙时如何跳转到可开锁的门。代码使用C++编写,涉及字符数组操作、二维数组访问、回溯和递归技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://acm.nyist.net/JudgeOnline/problem.php?pid=82

分析:可以重复走,在找到新钥匙的时候,可以跳到门的地方(可以到达改门)判断是否可以打开门。


#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

const int NM=25;
char str[NM][NM];

int dx[NM],dy[NM],key[NM],get[NM],n,m;
bool vis[NM][NM],flag;
int d[4][2]={-1,0,1,0,0,-1,0,1};

void DFS(int x,int y){
	int x1,y1,i,t;
	if(flag) return;
	if(str[x][y]=='G'){
		flag=true;return;
	}
	for(i=0;i<4;i++){
		x1=x+d[i][0];y1=y+d[i][1];
		if(x1>=0&&x1<n && y1>=0&&y1<m && !vis[x1][y1] && str[x1][y1]!='X'){
			vis[x1][y1]=1;  //DFS和BFS一样,到达某点的时候,已经把该点能够产生的情况都考虑在内了,所以<strong>不用回溯</strong>
			if(str[x1][y1]>='A' && str[x1][y1]<='E'){
				t=str[x1][y1]-'A';
				dx[t]=x1,dy[t]=y1;
				if(get[t]==key[t]) DFS(x1,y1);
			}
			else if(str[x1][y1]>='a' && str[x1][y1]<='e'){
				t=str[x1][y1]-'a';
				get[t]++;
				if(dx[t]!=-1) DFS(dx[t],dy[t]);  //能够到达门所在的位置
				else DFS(x1,y1);
			}
			else DFS(x1,y1);
		}
	}
}


int main()
{
	int sx,sy,i,j;
	while(scanf("%d%d",&n,&m) && (n||m)){
		memset(key,0,sizeof(key));
		memset(dx,-1,sizeof(dx));memset(dy,-1,sizeof(dy));
		memset(get,0,sizeof(get));
		for(i=0;i<n;i++){
			scanf("%s",str[i]);
			for(j=0;j<=m;j++){
				if(str[i][j]>='a' && str[i][j]<='e')
					key[str[i][j]-'a']++;
				else if(str[i][j]=='S') sx=i,sy=j;
			}
		}
		flag=false;
		memset(vis,0,sizeof(vis));
		vis[sx][sy]=1;
		DFS(sx,sy);
		if(flag) printf("YES\n");
		else printf("NO\n");
	}
	return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值