迷宫寻宝 南阳82题

思路:循环广搜 先广搜一次看看能不能到终点;如果不能则终点是被门挡住了。再广搜一次找钥匙;如果找不到钥匙了则找不到终点了;在广搜一次开门;

迷宫寻宝(一)

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 4
描述

一个叫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
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define QUEUELEN 1000
typedef struct  
{
	int x; 
	int y;
}DATA;

typedef struct  
{
	DATA data[QUEUELEN];
	int head;
	int tail;
}SQType;
//队列的初始化
SQType *SQTypeInit()
{
	SQType *q;
	if(q=(SQType *)malloc(sizeof(SQType)))
	{
		q->head=0;
		q->tail=0;
        return q;
	}
	else
	{
		return NULL;
	}
}
//判断空队列
int SQTypeIsEmpty(SQType *q)
{
	int temp;
	temp=q->head==q->tail;
	return temp;

}
int InSQType(SQType *q,DATA data)
{
	if (q->tail==QUEUELEN)
	{
		printf("队列满鸟。。。");
		return 0;
	}
	else
	{
		q->data[q->tail++]=data;
		return 1;
	}
}

//出队列
int  OutSQType(SQType *q,DATA &a)
{
	if(q->head==q->tail)
	{
	   printf("亲,队列是空的。。。");
	   return 0;
	}
	else
{  a= q->data[q->head++];
   
   return 1;
		
	}

};
char a[22][22];
int d1[5],d2[5];
int m,n,c,c1,f;
bool bfs2(int x,int y,int &k);
bool bfs(int x,int y,int &b)
{
  int dir[4][2]={1,0,-1,0,0,1,0,-1}; 
  int flag[21][21]={0};
   SQType *yao=SQTypeInit();
    DATA s={x,y};
    flag[x][y]=1;
    InSQType(yao,s);
   while(!SQTypeIsEmpty(yao))
   {
   	OutSQType(yao,s);
    for(int i=0;i<4;i++)
   	{
   		int nx=s.x+dir[i][0];  
   		int ny=s.y+dir[i][1];
   		if(a[nx][ny]>='a'&&a[nx][ny]<='e')
   		{ 
   		 c++; 	d2[a[nx][ny]-'a']++; b=1;a[nx][ny]='.';
   		}
   		if(a[nx][ny]=='.'&&!flag[nx][ny]&&nx>=0&&nx<m&&ny>=0&&ny<n)
   		{  
   			DATA n;
   			n.x=nx;
   			n.y=ny;
   			flag[nx][ny]=1;
   	        InSQType(yao,n);
   	      
   		}
   	}
   	 
   }
   }
bool bfs1(int x,int y,int &b)
{
	int dir[4][2]={1,0,-1,0,0,1,0,-1}; 
    int flag[21][21]={0};
    SQType *yao=SQTypeInit();
    DATA s={x,y};
    flag[x][y]=1;
    InSQType(yao,s);
   while(!SQTypeIsEmpty(yao))
   {
   	 OutSQType(yao,s);
   	 for(int i=0;i<4;i++)
   	{
   		int nx=s.x+dir[i][0];  
   		int ny=s.y+dir[i][1];
   		if(a[nx][ny]>='A'&&a[nx][ny]<='E')
   		{                 
   		  if(d1[a[nx][ny]-'A']==d2[a[nx][ny]-'A']) 
   		  {
   		  	a[nx][ny]='.'; b=1;
   		  }
   		}
   		if(a[nx][ny]=='.'&&!flag[nx][ny]&&nx>=0&&nx<m&&ny>=0&&ny<n)
   		{  
   			DATA n;
   			n.x=nx;
   			n.y=ny;
   			flag[nx][ny]=1;
   	        InSQType(yao,n);
   	      
   		}
   	} 
   }
}
bool bfs2(int x,int y,int &k)
{
	int dir[4][2]={1,0,-1,0,0,1,0,-1}; 
    int flag[21][21]={0};
    SQType *yao=SQTypeInit();
    DATA s={x,y};
    flag[x][y]=1;
    InSQType(yao,s);
   while(!SQTypeIsEmpty(yao))
   {
   	 OutSQType(yao,s);
   	 for(int i=0;i<4;i++)
   	{
   		int nx=s.x+dir[i][0];  
   		int ny=s.y+dir[i][1];
   		if(a[nx][ny]=='G')
   		{
   		  printf("YES\n");k=1;
   		  return 1; 
   		}
   		if(a[nx][ny]=='.'&&!flag[nx][ny]&&nx>=0&&nx<=m&&ny>=0&&ny<n)
   		{
   			DATA n1;
   			n1.x=nx;
   			n1.y=ny;
   			flag[nx][ny]=1;
   	        InSQType(yao,n1);
   	      
   		}
   	} 
   }
}
int main()
{   int x,y,zx,zy;
	while(scanf("%d%d",&m,&n)==2)
	{  if(m==0) break;  
	     
	  
	   for(int i=1;i<=m;i++)
	   { getchar();
	   	scanf("%s",a[i]);
	   }
	   
		for(int i=0;i<m;i++)
		{  
			for(int j=0;j<n;j++)
			{
				
				if(a[i][j]=='S')
				{
					x=i;
					y=j;a[i][j]='.'; 
				}
				
			
				if(a[i][j]>='a'&&a[i][j]<='e')
				{
					d1[a[i][j]-'a']++;
				}
			
			}
		}int b11=0; 
		while(11)
		{ 
		 
		 int k=0;
		    bfs2(x,y,k);
		   if(k==1) { 
		    b11=1;break;}
		     int b=0;
		     bfs(x,y,b);
		    if(b==0) break;
		    b=0;
		    bfs1(x,y,b);
		    if(b==0) break;
		    
		    
		  		
		} 
		if(b11==0)printf("NO\n");
		memset(d1,0,sizeof(d1));
		memset(d2,0,sizeof(d2));
	/*	int b=0;
		bfs(x,y,b);
		if(b<c){
		  printf("NO\n");continue;}
		//printf("%d\n",b);
		if(c1==0) { int k=0;
		 bfs2(x,y,k);
		 if(k==0) printf("NO\n"); continue;}
	    b=0;
		     bfs1(x,y,b);//printf("%d\n",b);
		if(!b) printf("NO\n");*/
		
	}
}        


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值