这道题,用floodfill做的,首先floodfill把所有能走到的点走完,然后统计找到的钥匙数量,如果某个门的钥匙全部找到,就把相应的门打开,重新floodfill,直到达到G点或者不能再扩展。
注意本题每行后有若干空格,我就是没有注意这点,被玩了几个小时……
#include<iostream>
using   namespace  std;
char  map[21][21];
int  h,w;
bool  visit[21][21];
int  num[6],cnt[6],open[6],sx,sy,ex,ey;
bool  flag=0;
bool  ok( int  x, int  y) //是否可达 
{
    
if (x>=1&&x<=h&&y>=1&&y<=w&&!visit[x][y]&&map[x][y]!='X'&&(map[x][y]<'A'||map[x][y]>'E'))
        
return  1;
    
return  0;
}
int  searchdoor( int  q) //打开门 
{   
    
int  i,j;
    
for (i=1;i<=h;i++)
    {
        
for (j=1;j<=w;j++)
        {
            
if (map[i][j]=='A'+q-1)
                map[i][j]='.';
        }
    }
    open[q]=1;
    
return  0;
}
bool  iskey( int  x, int  y) //判断是否为钥匙 
{
    
if (map[x][y]>='a'&&map[x][y]<='e')
        
return  1;
    
return  0;
}
int  floodfill( int  x, int  y) //灌水 
{   
    
bool  canmove=0;
    
if (x==ex&&y==ey)
    {
        flag=1;
        
return  0;
    }
    visit[x][y]=1;
    
if (iskey(x,y))
    {
        cnt[map[x][y]-'a'+1]++;
    }
    
if (ok(x+1,y))
    {   
        canmove=1;
        floodfill(x+1,y);
    }
    
if (ok(x-1,y))
    {   
        canmove=1;
        floodfill(x-1,y);
    }
    
if (ok(x,y+1))
    {
        canmove=1;
        floodfill(x,y+1);
    }
    
if (ok(x,y-1))
    {
        canmove=1;
        floodfill(x,y-1);
    }
    
if (!canmove)
    {   
        
int  i;
        
for (i=1;i<=5;i++)
        {   
            
if (cnt[i]>0&&cnt[i]==num[i]&&!open[i])
            {
                searchdoor(i);
                memset(visit,0,
sizeof (visit));
                memset(cnt,0,
sizeof (cnt));
                floodfill(sx,sy);
            }
        }
    }
}
int  main()
{
    
while (cin>>h>>w)
    {   
        
if (h==0&&w==0)
            
break ;
        memset(visit,0,
sizeof (visit));
        memset(map,'\0',
sizeof (map));
        memset(num,0,
sizeof (num));
        memset(cnt,0,
sizeof (num));
        memset(open,0,
sizeof (open));
        
int  i,j;
        
for (i=1;i<=h;i++)
        {
            
for (j=1;j<=w;j++)
            {
                cin>>map[i][j];
                
if (map[i][j]=='S')
                {
                    sx=i;
                    sy=j;
                }
                
if (map[i][j]=='G')
                {   
                    ex=i;
                    ey=j;
                }
                
if (map[i][j]>='a'&&map[i][j]<='e')
                {
                    num[map[i][j]-'a'+1]++;
                }
                
            }
        }
        flag=0;
        floodfill(sx,sy);
        
if (flag)
            cout<<"YES"<<endl;
        
else  
            cout<<"NO"<<endl;
    }
    system("pause");
    
return  0 ;
    
}