http://acm.nyist.net/JudgeOnline/problem.php?pid=82
#include <stdio.h> #include <memory.h> #define M 25 typedef struct{ int x; int y; int num; }Move; Move move[4]={{-1,0,0},{0,1,0},{1,0,0},{0,-1,0}},door[6];//保存门的坐标 int m,n,key[5],find[5],visit[M][M],arr[5],flag; char g[M][M]; void check(); void dfs(int x,int y); void check() { int a,b,i,j,k; for(i=0;i<5;i++) { if(door[i].num) //如果有门的话 (门的坐标存在) { a=door[i].x; b=door[i].y; if(find[i]==key[i]) // 钥匙都找到了 并且以前到过这里 或者现在在这里(能到达门这个位置) { dfs(a,b); } } } } void dfs(int x,int y) { visit[x][y]=1; int i,j,k,a,b; if(!flag) { for(i=0;i<4;i++) { a=x+move[i].x; b=y+move[i].y; if(a>=0&&a<m&&b>=0&&b<n&&g[a][b]!='X'&&!visit[a][b]) { if(g[a][b]=='.') { dfs(a,b); continue; } if(g[a][b]>='a'&&g[a][b]<='e')// 找到钥匙后 可以继续走或者去开门 { find[g[a][b]-'a']++; dfs(a,b); check();// 看能否开 } if(g[a][b]>='A'&&g[a][b]<='E') { door[g[a][b]-'A'].num++; //门存在 且到达了 door[g[a][b]-'A'].x=a; door[g[a][b]-'A'].y=b; visit[a][b]=1; //心塞!!! 有走过一定要标记阿 !!! check();// 看能否开 } if(g[a][b]=='G') { visit[a][b]=1; flag=1; break; } } } } } int main() { int i,j,k,x,y,s1,s2,g1,g2; while(scanf("%d%d",&m,&n)&&(m||n)) { flag=0; memset(door,0,sizeof(door)); memset(visit,0,sizeof(visit)); memset(key,0,sizeof(key)); //钥匙个数 memset(find,0,sizeof(find));//找到个数 for(i=0;i<m;i++) { scanf("%s",g[i]); for(j=0;j<n;j++) { if(g[i][j]>='a'&&g[i][j]<='e') { key[g[i][j]-'a']++; //需要钥匙的数量 } if(g[i][j]=='S') { s1=i; s2=j; } } } dfs(s1,s2); if(flag) printf("YES\n"); else printf("NO\n"); } return 0; }