逃离迷宫 bfs

链接:https://www.nowcoder.com/acm/contest/96/G
来源:牛客网
题目描述


给你一个n*m的图,地图上'.'代表可以走的地方,而'#'代表陷阱不能走, 'P'代表人物位置,'K'代表钥匙,'E'代表出口。人物一个,钥匙有多个, ('K'的数量<=50)),出口一个,每个位置可以向(上,下,左,右)四个 方向走一格,花费一个单位时间,现在你需要花费最少的时间拿到钥匙 然后从迷宫的出口出去(若没有钥匙,则不能进入迷宫出口所在的格子)。
输入描述:
第一行一个整数T(T <= 50),代表数据的组数接下来一行n,m(n<=500,m<=500),代表地图的行和列接下来n行,每行一个长度为m的字符串,组成一个图。
输出描述:
如果可以出去,输出所花费的最少时间。如果不能出去,输出一行"No solution"。

示例1

输入
3
5 5
....P
##..E
K#...
##...
.....
5 5
P....
.....
..E..
.....
....K
5 5
P#..E
.#.#.
.#.#.
.#.#.
...#K



输出
No solution
12
No solution
思路:vis数组三维,除了要保存是否访问,第三维额外保存当前有无钥匙的状态。
Code:
/*#include <bits/stdc++.h>
using namespace std;
const int AX = 5e2+66;
struct Node{
	int x,y,k;
};
int dir[4][2] = {
	{1,0},
	{0,1},
	{-1,0},
	{0,-1}
};
char G[AX][AX];
int n , m ;
int vis[AX][AX][2];

int bfs( int x, int y ){
	memset( vis , -1 , sizeof(vis) );
	queue<Node>que;
	Node tmp ;
	tmp.x = x ;
	tmp.y = y ;
	tmp.k = 0;
	vis[x][y][tmp.k] = 0;
	que.push(tmp);
	while( !que.empty() ){
		Node q = que.front();
		que.pop();
		if( G[q.x][q.y] == 'E' && q.k ) return vis[q.x][q.y][1];
		for( int i = 0 ; i < 4 ; i++ ){
			int xx = q.x + dir[i][0];
			int yy = q.y + dir[i][1];
			if( xx >= 0 && xx < n && yy >= 0 && yy < m && G[xx][yy] != '#' ){
				Node tp ;
				if( G[xx][yy] == 'K' ) tp.k = 1;
				else tp.k = q.k;
				if( vis[xx][yy][tp.k] != -1 ) continue;
				if( G[xx][yy] == 'E' && !tp.k ) continue;
				tp.x = xx;
				tp.y = yy;
				vis[tp.x][tp.y][tp.k] = vis[q.x][q.y][q.k] + 1;
				que.push(tp);
			}
		}

	}
	return -1;
}

int main(){
	int T;
	scanf("%d",&T);
	while( T-- ){
		int sx,sy;
		scanf("%d%d",&n,&m);
		for( int i = 0 ; i < n ; i++ ){
			scanf("%s",G[i]);
		}
		for( int i = 0 ; i < n ; i ++ ){
			for( int j = 0 ; j < m ; j++ ){
				if( G[i][j] == 'P' ){
					sx = i;
					sy = j;
					break;
				}
			}
		}
		int res = bfs(sx,sy);
		if( res != -1 ){
			cout << res << endl;
		}else{
			cout << "No solution" << endl;
		}
	}
	return 0 ;
}*/

#include <bits/stdc++.h>
using namespace std;
const int AX = 5e2+66;
struct Node{
	int x,y,step,k;
};
int dir[4][2] = {
	{1,0},
	{0,1},
	{-1,0},
	{0,-1}
};
char G[AX][AX];
int n , m ;
int vis[AX][AX][2];

int bfs( int x, int y ){
	memset( vis , 0 , sizeof(vis) );
	queue<Node>que;
	Node tmp ;
	tmp.x = x ;
	tmp.y = y ;
	tmp.k = 0;
	tmp.step = 0;
	vis[x][y][tmp.k] = 1;
	que.push(tmp);
	while( !que.empty() ){
		Node q = que.front();
		que.pop();
		if( G[q.x][q.y] == 'E') return q.step;
		for( int i = 0 ; i < 4 ; i++ ){
			int xx = q.x + dir[i][0];
			int yy = q.y + dir[i][1];
			if( xx >= 0 && xx < n && yy >= 0 && yy < m && G[xx][yy] != '#' ){
				Node tp;
				if( G[xx][yy] == 'K' ){
					tp.k = 1;
				}else tp.k = q.k;
				if( vis[xx][yy][tp.k] ) continue;
				vis[xx][yy][tp.k] = 1;
				if( G[xx][yy] == 'E' && !vis[xx][yy][1] ) continue;
				tp.x = xx;
				tp.y = yy;
				tp.step = q.step + 1 ;
				que.push(tp);
			}
		}
	}
	return -1;
}

int main(){
	int T;
	scanf("%d",&T);
	while( T-- ){
		int sx,sy;
		scanf("%d%d",&n,&m);
		for( int i = 0 ; i < n ; i++ ){
			scanf("%s",G[i]);
		}
		for( int i = 0 ; i < n ; i ++ ){
			for( int j = 0 ; j < m ; j++ ){
				if( G[i][j] == 'P' ){
					sx = i;
					sy = j;
					break;
				}
			}
		}
		int res = bfs(sx,sy);
		if( res != -1 ){
			cout << res << endl;
		}else{
			cout << "No solution" << endl;
		}
	}
	return 0 ;
}

阅读更多
版权声明:本文为博主原创文章,未经博主允许也可以转载。 https://blog.csdn.net/FrankAx/article/details/79950634
个人分类: 图-BFS
上一篇51nod 1280 前缀后缀集合
下一篇数学考试
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭