HNU 12894 Keys

来源:互联网 发布:淘宝安全证书 编辑:程序博客网 时间:2024/06/05 12:02

题意:

给你一个NXM的迷宫,$代表John要偷文件,.代表空,*代表墙,大写字母X表示门,x待变一个钥匙,X门可以用x开启

其中可能有多条X门,一个x钥匙可以开多条X门

迷宫外围任意一点都可以走

2<=N,M<= 100

 

方法:

对迷宫的每个边缘进行dfs,然后如果存在有门未遍历且有该门的钥匙则一直dfs,直到遍历完所有能遍历的门为止,其中每个遍历过的点进行标记,不再遍历

 

代码:

#include <cstdio>#include <cstring>struct node{int x,y;int flag;}z[10005];int zz[27];char m[111][111];int vis[111][111];int ans ,tot; //tot代表门的个数 int n, mm;int add_x[]= {1, -1, 0, 0};int add_y[]= {0, 0, 1, -1};void dfs(int x, int y){if(m[x][y]>='A' && m[x][y]<= 'Z'&&zz[m[x][y]-'A'+1]== 0){if(!vis[x][y]){tot++;z[tot].x= x;z[tot].y= y;z[tot].flag= m[x][y]- 'A' + 1;}return;}if(!vis[x][y]&&m[x][y]>='a' && m[x][y]<= 'z')zz[m[x][y]-'a'+1]= 1;vis[x][y]= 1;if(m[x][y]=='$')ans++;for(int i= 0; i< 4; i++){int xx= x+ add_x[i];int yy= y+ add_y[i];if(xx>= 1 && xx<= n && yy>= 0 && yy< mm && !vis[xx][yy]&& m[xx][yy]!='*')dfs(xx, yy);}}int main(){int T;scanf("%d",&T);while(T--){memset(vis, 0, sizeof(vis));scanf("%d %d",&n,&mm);for(int i= 1; i<= n; i++)scanf("%s",m[i]);memset(zz, 0, sizeof(zz));char ch[30];scanf("%s",ch+1);int len= strlen(ch+1);if(ch[1]!= '0')for(int i= 1; i<= len; i++)zz[ch[i]-'a'+1]= 1;ans= tot= 0;for(int i= 0; i< mm; i++){if(!vis[1][i]&& m[1][i]!='*')dfs(1, i);if(!vis[n][i] && m[n][i]!='*')dfs(n, i);}for(int i= 1; i<= n; i++){if(!vis[i][0]&& m[i][0]!='*')dfs(i, 0);if(!vis[i][mm-1] && m[i][mm-1]!='*')dfs(i, mm-1);}int p= 0;for(int i= 1; i<= tot; i++)if(vis[z[i].x][z[i].y]== 0 && zz[z[i].flag]){p= 1;break;}while(p){p= 0;for(int i= 1; i<= tot; i++)if(vis[z[i].x][z[i].y]== 0 && zz[z[i].flag]){dfs(z[i].x, z[i].y);}for(int i= 1; i<= tot; i++)if(vis[z[i].x][z[i].y]== 0 && zz[z[i].flag]){p= 1;break;}}printf("%d\n",ans);}return 0;}


 

 

0 0