UVA 1600 Patrol Robot(算法竞赛入门经典,bfs,经典)

算法竞赛入门经典177页,bfs,经典
题目意思:
有一个 n * m 大小的矩阵, 矩阵 只要数字 0 或者 1,0 表示空白可以走,1 表示有障碍物。
现在,要求 从起点 s(1, 1) 走到终点 t (n, m), 这两点都是空白。 每次走,可以连续穿过 k 个障碍物。
问,从 s(1, 1) 到 t (n, m) 至少走多少步。

本题要点:
1、这里的 “连续穿过 k 个障碍物” , 不一定是只要沿着一个方向走,这里的走可以是拐弯的走法。
所谓的拐弯,比如,从 点 (1, 1) ,右,下,下,左,就到达了点(3, 1)
2、如果没有k的限制,就是 bfs 的水题。加了限制,可以在原来二维 的vis数组加上第3维 layer。
vis[x][y][layer] 表示到达这一点 (x, y),已经连续穿过了layer个1。
首先,layer > 0 的时候,表示当前点(x, y) 是 mp[x][y] 是 1(如果 当前点是 0, 那么 layer 只能是 0);
vis[x][y][layer] == false, 进入到 点 (x, y) , 表示 从 之前的某点(假设点 (x0, y0)), 连续走了 layer 个 1, 才走到 点(x0, y0)。
3、 vis[x][y][layer] == true, 就不需要进入这点了。 已经有的点 (叫做 “早点” 吧) , “早点” 更早就进入队列了,
并且尝试了 连续走了 layer 个1 才走到了点 (x, y)。
所以,其他的点 连续走了 layer 个1 才走到了点 (x, y), 就不要再走了,因为有 “早点” 已经尝试过 了。
4、 代码是这位老哥的 点这里

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
const int MaxN = 25;
int n, m, k, T;
bool vis[MaxN][MaxN][MaxN];
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
int mp[MaxN][MaxN];
int cnt;

struct node
{
	int x, y;
	int step;
	int layer;
	node(int _x = 1, int _y = 1, int _step = 0, int _layer = 0)
	:x(_x), y(_y), step(_step), layer(_layer)
	{}
};

bool check(int x, int y)
{
	return x >= 1 && x <= n && y >= 1 && y <= m;
}

void bfs()
{
	queue<node> q;
	memset(vis, false, sizeof vis);
	node s(1, 1, 0, 0);
	node t(n, m);
	q.push(s);
	vis[1][1][0] = true;
	while(!q.empty())
	{
		node now = q.front();q.pop();
		if(now.x == t.x && now.y == t.y)
		{
			printf("%d\n", now.step);
			return;
		}
		int x, y, layer;
		for(int i = 0; i < 4; ++i)
		{
			x = now.x + dx[i], y = now.y + dy[i], layer = now.layer;
			if(mp[x][y])
			{
				layer++;
			}else{
				layer = 0;
			}
			if(layer <= k && check(x, y) && !vis[x][y][layer])
			{
				q.push(node(x, y,  now.step + 1, layer));
				vis[x][y][layer] = true;
			}
		}
	}
	printf("-1\n");
}

int main()
{
	scanf("%d", &T);
	while(T--)
	{
		scanf("%d%d%d", &n, &m, &k);
		for(int i = 1; i <= n; ++i)
			for(int j = 1; j <= m; ++j)
			{
				scanf("%d", &mp[i][j]);				
			}
		bfs();
	}
	return 0;
}

/*
3
2 5
0
0 1 0 0 0
0 0 0 1 0
4 6
1
0 1 1 0 0 0
0 0 1 0 1 1
0 1 1 1 1 0
0 1 1 1 0 0
2 2
0
0 1
1 0
*/

/*
7
10
-1
*/

猜你喜欢

转载自blog.csdn.net/qq_38232157/article/details/108367956