Gym 100187E - Two Labyrinths

11 篇文章 0 订阅

A labyrinth is the rectangular grid, each of the cellsof which is either free or wall, and it's possible to move only between freecells sharing a side.

Constantine and Mike are the world leaders ofcomposing the labyrinths. Each of them has just composed one labyrinth of sizen × m, and now they are blaming each other for theplagiarism. They consider that the plagiarism takes place if there exists sucha path from the upper-left cell to the lower-right cell that is the shortestfor both labyrinths. Resolve their conflict and say if the plagiarism tookplace.

Input

In the first line two integers n and m (1 ≤ n, m ≤ 500) arewritten — the height and the width of the labyrinths.

In the next n lines the labyrinth composed by Constantine iswritten. Each of these n lines consists of m characters. Eachcharacter is equal either to «#»,which denotes a wall, or to «.»,which denotes a free cell.

The next line is empty, and in the next n lines the labyrinthcomposed by Mike is written in the same format. It is guaranteed that theupper-left and the lower-right cells of both labyrinths are free.

Output

Output «YES» ifthere exists such a path from the upper-left to the lower-right cell that isthe shortest for both labyrinths. Otherwise output «NO».

Sample test(s)

input

3 5
.....
.#.#.
.....
  

.....
#.#.#
.....

output

NO

input

3 5
.....
.#.##
.....
 

.....
##.#.
.....

output

YES

 

思路:

三次bfs,第一次求A的最短路,接下来求B的最短路,如果步数不同则NO

第三次求共同最短路,如果步数与A相同输出YES


代码:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;

const int N = 505;

char a[N][N], b[N][N];
int n, m;
bool f[N][N];

int mx[] = { 1, 0, -1, 0 };
int my[] = { 0, 1, 0, -1 };

bool check(int x, int y, char t[][N])
{
	return (x >= 0 && y >= 0 && x < n && y < m && t[x][y] == '.');
}

bool check2(int x, int y)
{
	return (x >= 0 && y >= 0 && x<n && y<m && a[x][y] == '.' && b[x][y] == '.');
}

struct node
{
	int x, y, step;
};

int main()
{

	while (scanf("%d%d", &n, &m) != EOF)
	{
		int i;
		for (i = 0; i<n; i++)
			scanf("%s", a[i]);
		for (i = 0; i<n; i++)
			scanf("%s", b[i]);


		node now, temp;
		bool flag;
		queue<node> q;
		int stepa, stepb, stepc;
		stepa = stepb = stepc;

		memset(f, true, sizeof(f));

		f[0][0] = false;
		now.x = now.y = now.step = 0;
		q.push(now);

		while (!q.empty())
		{
			now = q.front();
			int tx, ty;

			if (now.x == n - 1 && now.y == m - 1)
			{
				stepa = now.step;
				break;
			}

			for (i = 0; i<4; i++)
			{
				tx = now.x + mx[i];
				ty = now.y + my[i];
				if (check(tx, ty, a) && f[tx][ty])
				{
					temp.x = tx;
					temp.y = ty;
					temp.step = now.step + 1;
					f[tx][ty] = false;
					q.push(temp);
				}
			}

			q.pop();
		}

		while (!q.empty())
			q.pop();

		memset(f, true, sizeof(f));

		f[0][0] = false;
		now.x = now.y = now.step = 0;
		q.push(now);

		while (!q.empty())
		{
			now = q.front();
			int tx, ty;

			if (now.x == n - 1 && now.y == m - 1)
			{
				stepb = now.step;
				break;
			}

			for (i = 0; i<4; i++)
			{
				tx = now.x + mx[i];
				ty = now.y + my[i];
				if (check(tx, ty, b) && f[tx][ty])
				{
					temp.x = tx;
					temp.y = ty;
					temp.step = now.step + 1;
					f[tx][ty] = false;
					q.push(temp);
				}
			}

			q.pop();
		}

		if (stepa != stepb)
		{
			printf("NO\n");
			continue;
		}

		while (!q.empty())
			q.pop();

		memset(f, true, sizeof(f));
		flag = false;

		f[0][0] = false;
		now.x = now.y = now.step = 0;
		q.push(now);

		while (!q.empty())
		{
			now = q.front();
			int tx, ty;

			if (now.step>stepa)
			{
				break;
			}

			if (now.x == n - 1 && now.y == m - 1 && now.step == stepa)
			{
				flag = true;
				break;
			}

			for (i = 0; i<4; i++)
			{
				tx = now.x + mx[i];
				ty = now.y + my[i];
				if (check2(tx, ty) && f[tx][ty])
				{
					temp.x = tx;
					temp.y = ty;
					temp.step = now.step + 1;
					f[tx][ty] = false;
					q.push(temp);
				}
			}

			q.pop();
		}

		if (flag)
		{
			printf("YES\n");
		}
		else
			printf("NO\n");
	}


	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值