NOJ 82 迷宫寻宝(一)

题目链接~~>

                   思路:先用 dfs( ) 找钥匙,再用 bfs( ) 找门(如果在找钥匙或找门的过程中发现宝藏则结束),找到门时看一下钥匙是否足够,如果打开一扇门接着 dfs( ) 去寻找钥匙(有可能打开一扇门里面有钥匙),一直寻找完。

代码:

#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std ;
int n,m,f,mkey ; // mkey 找到钥匙的数量
int g[10],vis[25][25],vix[25][25][100] ; // 广搜时每增加一个钥匙就可以走回头路
int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1} ;  // 和胜利大逃亡(续)思想一样
char s[25][25] ;
struct zhang
{
    int x,y ;
} ;
int search(int x,int y)//判断是否满足条件
{
    if((s[x][y]>='A'&&s[x][y]<='E')||s[x][y]=='X')
               return  0 ;
    if(x<0||x>=n||y<0||y>=m||vis[x][y])
               return  0 ;
    if(s[x][y]>='a'&&s[x][y]<='e')//找到一把钥匙则对应钥匙减一
    {
        int k=s[x][y]-'a' ;
        g[k]-- ;
        mkey++ ;
    }
    return  1 ;
}
void dfs(int i,int j)// 深搜找钥匙
{
    if(s[i][j]=='G'||f) { f=1 ;return ;}
    if(search(i-1,j)) { vis[i-1][j]=1 ;dfs(i-1,j) ;}
    if(search(i+1,j)) { vis[i+1][j]=1 ;dfs(i+1,j) ;}
    if(search(i,j-1)) { vis[i][j-1]=1 ;dfs(i,j-1) ;}
    if(search(i,j+1)) { vis[i][j+1]=1 ;dfs(i,j+1) ;}
}
int bfs(int x,int y)// 广搜找门
{
     queue<zhang>q ;
     zhang current,next ;
     memset(vix,0,sizeof(vix)) ;
     current.x=x ;
     current.y=y ;
     vix[x][y][mkey]=1 ;
     q.push(current) ;
     while(!q.empty())
     {
           current=q.front() ;
           q.pop() ;
           if(s[current.x][current.y]=='G'||f)
                  return  1 ;
           for(int i=0;i<4;i++)
           {
               next.x=current.x+dx[i] ;
               next.y=current.y+dy[i] ;
               if(next.x>=0&&next.x<n&&next.y>=0&&next.y<m&&s[next.x][next.y]!='X'&&!vix[next.x][next.y][mkey])
               {
                   vix[next.x][next.y][mkey]=1 ;
                   if(s[next.x][next.y]>='A'&&s[next.x][next.y]<='E')
                   {
                        int key=s[next.x][next.y]-'A' ;
                        if(!g[key])
                        {
                            s[next.x][next.y]='.' ;
                            dfs(next.x,next.y) ;
                            q.push(next) ;
                        }
                   }
                   else
                            q.push(next) ;
               }
           }
     }
     return 0 ;
}
int main()
{
    int i,j,rx,ry ;
    while(scanf("%d %d",&n,&m)!=EOF)
    {
         if(!n&&!m)
                     break ;
         memset(g,0,sizeof(g)) ;
         memset(vis,0,sizeof(vis)) ;
         for(i=0;i<n;i++)
         {
             scanf("%s",s[i]) ;
             for(j=0;j<m;j++)
             {
                 if(s[i][j]=='S')
                 {
                     rx=i ;
                     ry=j ;
                 }
                 else if(s[i][j]>='a'&&s[i][j]<='e')//储存钥匙
                 {
                     int k=s[i][j]-'a' ;
                     g[k]++ ;
                 }
             }
         }
         f=0 ;mkey=0 ;
         vis[rx][ry]=1 ;
         dfs(rx,ry) ;
         if(f)
         {
             printf("YES\n") ;
             continue ;
         }
         int mx=bfs(rx,ry) ;
         if(mx!=0)
                       printf("YES\n") ;
         else          printf("NO\n") ;
    }
    return  0 ;
}



 

你可能感兴趣的:(NOJ 82 迷宫寻宝(一))