迷宫寻宝(一) 搜索

迷宫寻宝(一)

时间限制: 1 Sec   内存限制: 64 MB
提交: 24   解决: 7
[ 提交][ 状态][ 讨论版]

题目描述

一个叫ACM的寻宝者找到了一个藏宝图,它根据藏宝图找到了一个迷宫,这是一个很特别的迷宫,迷宫里有N个编过号的门(N<=5),它们分别被编号为A,B,C,D,E.为了找到宝藏,ACM必须打开门,但是,开门之前必须在迷宫里找到这个打开这个门所需的所有钥匙(每个门都至少有一把钥匙),例如:现在A门有三把钥匙,ACM就必须找全三把钥匙才能打开A门。现在请你编写一个程序来告诉ACM,他能不能顺利的得到宝藏。

输入

输入可能会有多组测试数据(不超过10组)。
每组测试数据的第一行包含了两个整数M,N(1<N,M<20),分别代表了迷宫的行和列。接下来的M每行有N个字符,描述了迷宫的布局。其中每个字符的含义如下:
.表示可以走的路
S:表示ACM的出发点
G表示宝藏的位置
X表示这里有墙,ACM无法进入或者穿过。
A,B,C,D,E表示这里是门,a,b,c,d,e表示对应大写字母的门上的钥匙。
注意ACM只能在迷宫里向上下左右四个方向移动。

最后,输入0 0表示输入结束。

输出

每行输出一个YES表示ACM能找到宝藏,输出NO表示ACM找不到宝藏。

样例输入

4 4 
S.X. 
a.X. 
..XG 
.... 
3 4 
S.Xa 
.aXB 
b.AG 
0 0

样例输出

YES 
NO
# include<stdio.h>
# include<queue>
# include<string.h>
using namespace std;
int b[4][2]={0,1,1,0,-1,0,0,-1};//上下左右四个方向 
char a1[25][25];
int v[25][25];//标记走过的路 
int n,m,k1[6],k2[6],s1,s2,k;
struct node{
    int x,y;    
};
int dfs()
{   
k=0;
memset(v,0,sizeof(v));
    queue<node>s;
    node p,q; 
    p.x=s1;
    p.y=s2;
    s.push(p); v[s1][s2]=1;
    while(!s.empty())
    {
    p=s.front();
        s.pop(); 
        if(a1[p.x][p.y]=='G')//如果找到宝箱 
        return 1;
        for(int i=0;i<4;i++)
        {
            q.x=p.x+b[i][0];
            q.y=p.y+b[i][1];
            if(q.x>=0&&q.x<n&&q.y>=0&&q.y<m&&a1[q.x][q.y]>='a'&&a1[q.x][q.y]<='e')
            {    k2[a1[q.x][q.y]-'a']++;
            a1[q.x][q.y]='.';
			k=1;//找到钥匙 
            }
            if(q.x>=0&&q.x<n&&q.y>=0&&q.y<m&&!v[q.x][q.y]&&a1[q.x][q.y]!='X')
            {
                if(a1[q.x][q.y]>='A'&&a1[q.x][q.y]<='E')
                {
                    if(k2[a1[q.x][q.y]-'A']==k1[a1[q.x][q.y]-'A'])//找到的钥匙数与总共的钥匙数的关系 
                    {                    //如果相等这开门; 
                        s.push(q);
                    v[q.x][q.y]=1;
                    }
                }
                else {
                s.push(q);
                    v[q.x][q.y]=1;                  
                }
            }
                             
        }   
    }
 if(!k)    return -1;  //如果没找到钥匙 
else return 0;     //找到钥匙但没找到宝箱 
     
}
int main(){
    while(~scanf("%d%d",&n,&m)&&m&&n)
    {  getchar();
        int i,j;
        memset(k1,0,sizeof(k1));
        memset(k2,0,sizeof(k2));
        
    for(i=0;i<n;i++) 
        {
            scanf("%s",&a1[i]);
            for(j=0;j<m;j++)
            if(a1[i][j]>='a'&&a1[i][j]<='e')
            k1[a1[i][j]-'a']++;
            else if(a1[i][j]=='S'){
            s1=i;s2=j;  
            }
            getchar();
        }
        while(1)//每次都重新调用函数 
		{
			int w=dfs();
			if(w==1)  {  //如果返回值为1 说明已经找到宝箱 
				printf("YES\n");
				break;
			}
			else if(w==-1)  // 如果没有找到钥匙并且没有找到 宝箱 则说明不可能成功 
			{
				printf("NO\n");break;
			}
		  }  
    }
     
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值