题目很简单:就是给定一个矩形,abcde是钥匙,分别对应于它的大写字母(这些大写字母是門)
从S出发,求是否可以到达G点,通过钥匙开门到达G点
注意:这里可以很有很多的同一个字母(除了G S),也可以没有钥匙和門
深搜:
自己本来写的搜索错误,因为上面这些原因,而且自己对于递归的返回找不到很好的方式,也就是递归基,难以分辨后赋值并返回
注意:自己老是忘记,scanf对于末尾多余的空格是不会管的,本题中每一行末尾都有空格
#include<stdio.h> #include<string.h> struct pointer { int x; int y; }start; int M,N; char a[25][25]; int temp[110]; int tag[25][25]; int dx[]={0,0,1,-1}; int dy[]={1,-1,0,0}; void deal(char ch) { for(int i=0;i<M;i++) for(int j=0;j<N;j++) if(a[i][j]==ch) a[i][j]='.'; memset(tag,0,sizeof(tag)); } int dfs(int x,int y) { tag[x][y]=1; int tempx,tempy; for(int i=0;i<4;i++){ tempx=dx[i]+x; tempy=dy[i]+y; if(tempx<0||tempy<0||tempx>=M||tempy>=N) continue; if(a[tempx][tempy]=='G') return 1; if(a[tempx][tempy]>='a'&&a[tempx][tempy]<='e'&&tag[tempx][tempy]==0){ temp[a[tempx][tempy]]--; if(!temp[a[tempx][tempy]]){ deal(a[tempx][tempy]-32);<span style="white-space:pre"> </span>//有很多钥匙和門所以需要重新memset清除tag a[tempx][tempy]='.'; if(dfs(start.x,start.y)) return 1; } else{ a[tempx][tempy]='.'; if(dfs(tempx,tempy))<span style="white-space:pre"> </span>//注意,这里是重点,从头再开始搜索,因为可以有很多的钥匙和門 return 1; } continue; } if(a[tempx][tempy]=='.'&&tag[tempx][tempy]==0) if(dfs(tempx,tempy)) return 1; } return 0; } int main() { while(scanf("%d%d",&M,&N),M&&N) { memset(temp,0,sizeof(temp)); memset(tag,0,sizeof(tag)); for(int i=0;i<M;i++){ scanf("%s",a[i]);<span style="white-space:pre"> </span>//特殊的输入方式后再检测字符的方式,可以借鉴 for(int j=0;j<N;j++){ if(a[i][j]>='a'&&a[i][j]<='e') temp[a[i][j]]++; if(a[i][j]=='S'){ start.x=i; start.y=j; } } } if(dfs(start.x,start.y)) puts("YES "); else puts("NO"); } return 0; }