迷宫寻宝(一)
时间限制:1000 ms | 内存限制:65535 KB
难度:4
- 描述
-
一个叫ACM的寻宝者找到了一个藏宝图,它根据藏宝图找到了一个迷宫,这是一个很特别的迷宫,迷宫里有N个编过号的门(N<=5),它们分别被编号为A,B,C,D,E.为了找到宝藏,ACM必须打开门,但是,开门之前必须在迷宫里找到这个打开这个门所需的所有钥匙(每个门都至少有一把钥匙),例如:现在A门有三把钥匙,ACM就必须找全三把钥匙才能打开A门。现在请你编写一个程序来告诉ACM,他能不能顺利的得到宝藏。
- 输入
- 输入可能会有多组测试数据(不超过10组)。
每组测试数据的第一行包含了两个整数M,N(1<N,M<20),分别代表了迷宫的行和列。接下来的M每行有N个字符,描述了迷宫的布局。其中每个字符的含义如下:
.表示可以走的路
S:表示ACM的出发点
G表示宝藏的位置
X表示这里有墙,ACM无法进入或者穿过。
A,B,C,D,E表示这里是门,a,b,c,d,e表示对应大写字母的门上的钥匙。
注意ACM只能在迷宫里向上下左右四个方向移动。最后,输入0 0表示输入结束。
- 输出
- 每行输出一个YES表示ACM能找到宝藏,输出NO表示ACM找不到宝藏。
- 样例输入
-
4 4 S.X. a.X. ..XG .... 3 4 S.Xa .aXB b.AG 0 0
- 样例输出
-
YES NO
题解:
- num记录钥匙的个数;神搜,搜到钥匙就加上,遇到门就判断,带个回溯;但是不知道对不对,还在判题中;
- 代码:
-
1 #include<stdio.h> 2 #include<string.h> 3 int ans; 4 int disx[4]={0,0,1,-1}; 5 int disy[4]={1,-1,0,0}; 6 char map[20][20]; 7 int vis[20][20]; 8 int N,M; 9 int nx,ny; 10 int key[5],num[5]; 11 void dfs(int x,int y){ 12 if(map[x][y]==‘G‘){ 13 ans=1; 14 // puts("--------"); 15 return; 16 } 17 // puts("........"); 18 vis[x][y]=1; 19 for(int i=0;i<4;i++){ 20 nx=x+disx[i];ny=y+disy[i]; 21 if(nx<0||ny<0||nx>=N||ny>=M||map[nx][ny]==‘X‘||vis[nx][ny])continue; 22 if(map[nx][ny]==‘.‘||map[nx][ny]==‘G‘){ 23 dfs(nx,ny); 24 vis[nx][ny]=0; 25 } 26 else{ 27 if(map[nx][ny]>=‘a‘&&map[nx][ny]<=‘e‘){ 28 key[map[nx][ny]-‘a‘]++; 29 dfs(nx,ny); 30 key[map[nx][ny]-‘a‘]--; 31 vis[nx][ny]=0; 32 } 33 else{ 34 if(key[map[nx][ny]-‘A‘]==num[map[nx][ny]-‘a‘]){ 35 dfs(nx,ny); 36 vis[nx][ny]=0; 37 } 38 else continue; 39 } 40 } 41 } 42 return ; 43 } 44 int main(){ 45 int sx,sy; 46 while(~scanf("%d%d",&N,&M),N|M){ 47 memset(key,0,sizeof(key)); 48 memset(vis,0,sizeof(vis)); 49 memset(num,0,sizeof(num)); 50 ans=0; 51 for(int i=0;i<N;i++)scanf("%s",map[i]); 52 for(int i=0;i<N;i++)for(int j=0;j<M;j++){ 53 if(map[i][j]==‘S‘)sx=i,sy=j; 54 if(map[i][j]>=‘a‘&&map[i][j]<=‘e‘)num[map[i][j]-‘a‘]++; 55 } 56 //puts("***********"); 57 map[sx][sy]=‘X‘; 58 dfs(sx,sy); 59 //puts("++++"); 60 if(ans)puts("YES"); 61 else puts("NO"); 62 } 63 return 0; 64 }
时间: 2024-10-06 16:02:41