2009
11.07

http://acm.pku.edu.cn/JudgeOnline/problem?id=2157

这应该是我做过的较为复杂的搜索题了!

首先,对输入的数据进行处理,记录下每个门的位置,以及每个门各需要多少钥匙才能打开!

于是钥匙数据有两个变量:对应的门的钥匙数量,目前拿到的钥匙的数量(当这两个变量相等的时候,才可将对应的门打开!)

门的数组有有三个变量,x,y,open。x和y是记录该门的位置,而open则是判断是否在搜索的过程中到达这个门。

只有当open==true,还有钥匙的数量等于目前那道该种钥匙的数量时,该门才能作为新的起点进行新一轮的遍历!

切记,门是走不过去的,也就是遇到门的时候要将其标记为普通点,否则下次将该点作为起点进行遍历的时候会重复走。接着就returne 0.这个问题导致了2次TLE。

而钥匙的点作为普通的点就行了。

为了方便处理,将起点作为第五个门,呵呵,的确是方便了很多!

当门数组从头到位走一次,都没发现可以作为新起点的门的时候,说明此迷宫是拿不到宝藏的,输出NO。

That ’s all!

其实代码并不长,只是判断语句太多了!

乱码如下:

#include<stdio.h>
#include<string.h>
struct keys
{
	int total;
	int have;
}key[8];
struct point
{
	bool open;
	int x,y;
}list[8];
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
char g[21][21];
bool u[21][21],find;
int n,m;
int dfs(int x,int y)
{
	if(g[x][y]=='X')
		return 0;
	else if(g[x][y]=='G')
	{
		find=true;
		return 0;
	}
	else if(g[x][y]>='A' && g[x][y]<='E')
	{
		list[g[x][y]-'A'].open=true;
		g[x][y]='.';
		return 0;
	}
	else if(g[x][y]>='a' && g[x][y]<='e')
	{
		key[g[x][y]-'a'].have++;
	}
	int i,j,k,a,b;
	for(i=0;i<4;i++)
	{
		a=x+dir[i][0];
		b=y+dir[i][1];
		if(a>=0 && a<n && b>=0 && b<m && u[a][b])
		{
			u[a][b]=false;
			dfs(a,b);
			if(find)
				return 0;
		}
	}
}
int main()
{
//	freopen("1.txt","r",stdin);
	int i,j,k;
	while(scanf("%d %d",&n,&m)!=EOF)
	{
		find=false;
		memset(key,0,sizeof(key));
		memset(list,0,sizeof(list));
		memset(u,true,sizeof(u));
		if(n==0 && m==0)
			return 0;
		for(i=0;i<n;i++)
			scanf("%s",g[i]);
		for(i=0;i<n;i++)
		{
			for(j=0;j<m;j++)
			{
				if(g[i][j]=='.' || g[i][j]=='X')
					continue;
				else if(g[i][j]>='a' && g[i][j]<='e')
				{
					key[g[i][j]-'a'].total++;
				}
				else if(g[i][j]>='A' && g[i][j]<='E')
				{
					list[g[i][j]-'A'].x=i;
					list[g[i][j]-'A'].y=j;
					list[g[i][j]-'A'].open=false;
				}
				else if(g[i][j]=='S')
				{
					list[5].x=i;
					list[5].y=j;
					list[5].open=true;
				}
			}
		}
		while(1)
		{
			k=0;
			for(i=0;i<6;i++)
			{
				if(list[i].open && key[i].total==key[i].have)
				{
					k++;
					list[i].open=false;
					dfs(list[i].x,list[i].y);
				}
				if(find)
				{
					printf("YES\n");
					break;
				}
			}
			if(find)
				break;
			if(k==0)
			{
				printf("NO\n");
				break;
			}
		}
 
	}
 
	return 0;
}

暂无回复

添加回复