nyoj 82迷宫寻宝

http://acm.nyist.net/JudgeOnline/problem.php?pid=82

#include <stdio.h>
#include <memory.h>
#define M 25
typedef struct{
int x;
int y;
int num;
}Move;
Move move[4]={{-1,0,0},{0,1,0},{1,0,0},{0,-1,0}},door[6];//保存门的坐标  
int m,n,key[5],find[5],visit[M][M],arr[5],flag;
char g[M][M];


void check();
void dfs(int x,int y);
void check()
{
	int a,b,i,j,k;
	for(i=0;i<5;i++)
	{
		if(door[i].num) //如果有门的话 (门的坐标存在) 
		{
			a=door[i].x;
			b=door[i].y;
			if(find[i]==key[i]) // 钥匙都找到了  并且以前到过这里 或者现在在这里(能到达门这个位置) 
			{ 
		
			  dfs(a,b);  
			}
	
		}
}


}
void dfs(int x,int y)
{
		
		visit[x][y]=1;
	int i,j,k,a,b;
	if(!flag)
	{
		
		for(i=0;i<4;i++)
		{
			a=x+move[i].x;
			b=y+move[i].y;
			if(a>=0&&a<m&&b>=0&&b<n&&g[a][b]!='X'&&!visit[a][b])
			{
				if(g[a][b]=='.')
				{
					dfs(a,b);  
					continue;
				}
				if(g[a][b]>='a'&&g[a][b]<='e')// 找到钥匙后 可以继续走或者去开门	
				{
					find[g[a][b]-'a']++;
					dfs(a,b); 
					check();// 看能否开 
				}
				if(g[a][b]>='A'&&g[a][b]<='E')
				{ 
					door[g[a][b]-'A'].num++; //门存在 且到达了 
					door[g[a][b]-'A'].x=a;
					door[g[a][b]-'A'].y=b;
					visit[a][b]=1; //心塞!!! 有走过一定要标记阿 !!! 
					check();// 看能否开 
				}
				if(g[a][b]=='G')
				{
					visit[a][b]=1;
					flag=1;
					break;
				}
			
			}
			
		}
	}	
}
int main()	
{
	int i,j,k,x,y,s1,s2,g1,g2;
	while(scanf("%d%d",&m,&n)&&(m||n))
	{		
		flag=0;
		memset(door,0,sizeof(door));
		memset(visit,0,sizeof(visit));
		memset(key,0,sizeof(key)); //钥匙个数 
		memset(find,0,sizeof(find));//找到个数 
		
		for(i=0;i<m;i++)
		{
			scanf("%s",g[i]);
			for(j=0;j<n;j++)
			{
				
				if(g[i][j]>='a'&&g[i][j]<='e')
				{
					key[g[i][j]-'a']++; //需要钥匙的数量 
				}
				if(g[i][j]=='S')
				{
					s1=i;
					s2=j;
				}
			
			}
		}
		dfs(s1,s2);  
		if(flag)
		printf("YES\n");
		else
		printf("NO\n");
	}
		return 0;
}   


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值