nyoj 82 搜索

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

一个叫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

题目理解错误,它首先必须找全所有的钥匙

用的深搜,竟然超时。。用广搜,不知错哪里。。

引用别人的bfs

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<vector>
using namespace std;
int p = 1;
#define CLR(arr, what) memset(arr, what, sizeof(arr))
const int N = 25, M = 5;
const char dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; 

struct node{
	int x, y;
}src, des, doorpos[5];      

char maze[N][N];     
bool visit[N][N];     
bool door[5];      
int key[5];         
int row, col;
queue<node> q;

bool travel(node cur) 
{
	if(cur.x < 0 || cur.y < 0 || cur.x >= row || cur.y >= col || maze[cur.x][cur.y] == 'X')
		return false;
	return true;
}

bool check()
{
	for(int i = 0; i < 5; ++i)
		if(key[i] != 0)
			return false;
	return true;
}

bool BFS()
{
	q.push(src);
	visit[src.x][src.y] = true;
	while(!q.empty())
	{
		node cur, temp;
		cur = q.front();
		q.pop();	
		visit[src.x][src.y] = false;

		if(maze[cur.x][cur.y] >= 'a' && maze[cur.x][cur.y] <= 'e' && key[maze[cur.x][cur.y] - 'a'] > 0)
		{
			key[maze[cur.x][cur.y] - 'a']--;
			if(key[maze[cur.x][cur.y] - 'a'] == 0 && door[maze[cur.x][cur.y] - 'a'] == true)
			{
				node in;
				in.x = doorpos[maze[cur.x][cur.y] - 'a'].x;
				in.y = doorpos[maze[cur.x][cur.y] - 'a'].y;
				if(maze[in.x][in.y] == 'X')
					q.push(in);
			}
		}
		if(maze[cur.x][cur.y] >= 'A' && maze[cur.x][cur.y] <= 'E')
		{
			if(key[maze[cur.x][cur.y] - 'A'] > 0)
			{
				maze[cur.x][cur.y] = 'X';
				continue;
			}
		}
		maze[cur.x][cur.y] = 'X';

		if(cur.x == des.x && cur.y == des.y && check()) 
			return true;

		for(int i = 0; i < 4; ++i) 
		{
			temp.x = cur.x + dir[i][0]; temp.y = cur.y + dir[i][1];
			if(travel(temp) == false || visit[temp.x][temp.y])
				continue;
			q.push(temp);
			visit[temp.x][temp.y] = true;
		}

	}
	return false;
}

int main()
{
	while(scanf("%d%d", &row, &col) && (row + col))
	{
		CLR(door, false); CLR(key, 0); CLR(visit, false);
		for(int i = 0; i < 5; ++i)
		{	doorpos[i].x = -1; doorpos[i].y = -1;}
		while(!q.empty())
			q.pop();
		for(int i = 0; i < row; ++i) //迷宫处理
		{
			scanf("%s", maze[i]);
			for(int j = 0; j < col; ++j)
			{
				if(maze[i][j] == 'S')
					src.x = i, src.y = j;
				else if(maze[i][j] == 'G')
					des.x = i, des.y = j;
				else if(maze[i][j] >= 'A' && maze[i][j] <= 'E')
				{
					door[maze[i][j] - 'A'] = true;
					doorpos[maze[i][j] - 'A'].x = i;
					doorpos[maze[i][j] - 'A'].y = j;
				}
				else if(maze[i][j] >= 'a' && maze[i][j] <= 'e')
					key[maze[i][j] - 'a']++;
			}
		}

		printf(BFS() ? "YES\n" : "NO\n");
	}
	return 0;
}


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值