题意:人走迷宫,起点S,终点G,A/B/C/D/E为门,要开A必须集齐地图上所有的a,依次类推,问最后能否到G。

题解:从起点出发,dfs所有能到的点,其中,遇到门但没凑够钥匙就将该点标记,代表能到它,遇到钥匙就将还需要凑的钥匙减一。然后每次dfs一遍后,查看所有的被标记了的门,如果钥匙够了就从该点出发再进行一次dfs。

View Code
  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<cctype>
  5 using namespace std;
  6 int r,c;
  7 char map[30][30];
  8 int num[30],po[30][2];
  9 bool vis[30][30];
 10 bool in(int x,int y)
 11 {
 12     return (x>=1&&x<=r&&y>=1&&y<=c&&map[x][y]!='X');
 13 }
 14 bool dfs(int x,int y)
 15 {
 16     if(map[x][y]=='G')
 17         return true;
 18     vis[x][y]=true;
 19     if(isupper(map[x][y])&&num[map[x][y]-'A']!=0)
 20         return false;
 21     if(islower(map[x][y]))
 22         num[map[x][y]-'a']--,map[x][y]='.';
 23     bool flag=false;
 24     if(in(x+1,y)&&!vis[x+1][y])
 25         flag=flag||dfs(x+1,y);
 26     if(in(x-1,y)&&!vis[x-1][y])
 27         flag=flag||dfs(x-1,y);
 28     if(in(x,y+1)&&!vis[x][y+1])
 29         flag=flag||dfs(x,y+1);
 30     if(in(x,y-1)&&!vis[x][y-1])
 31         flag=flag||dfs(x,y-1);
 32     return flag;
 33 }
 34 int main()
 35 {
 36     while(scanf("%d%d",&r,&c),(r||c))
 37     {
 38         memset(num,-1,sizeof(num));
 39         memset(vis,false,sizeof(vis));
 40         int x,y;
 41         for(int i=1;i<=r;i++)
 42         {
 43             scanf("%s",map[i]+1);
 44             for(int j=1;j<=c;j++)
 45             {
 46                 char ch=map[i][j];
 47                 if(isalpha(ch))
 48                 {
 49                     if(islower(ch))
 50                     {
 51                         if(num[ch-'a']==-1)
 52                             num[ch-'a']=1;
 53                         else
 54                             num[ch-'a']++;
 55                     }
 56                     else if(ch<='E')
 57                     {
 58                         po[ch-'A'][0]=i;
 59                         po[ch-'A'][1]=j;
 60                         if(num[ch-'A']==-1)
 61                             num[ch-'A']=0;
 62                     }
 63                     else if(ch=='S')
 64                     {
 65                         x=i;y=j;
 66                         map[i][j]='.';
 67                     }
 68                 }
 69             }
 70         }
 71         if(dfs(x,y))
 72         {
 73             printf("YES\n");
 74             continue;
 75         }
 76         while(1)
 77         {
 78             bool flag=false;
 79             for(int i=0;i<5;i++)
 80             {
 81                 if(num[i]==0)
 82                 {
 83                     x=po[i][0];
 84                     y=po[i][1];
 85                     if(!vis[x][y])
 86                         continue;
 87                     num[i]--;
 88                     flag=true;
 89                     map[x][y]='.';
 90                     break;
 91                 }
 92             }
 93             if(!flag)
 94             {
 95                 printf("NO\n");
 96                 break;
 97             }
 98             else if(dfs(x,y))
 99             {
100                 printf("YES\n");
101                 break;
102             }
103         }
104     }
105     return 0;
106 }