【dfs】无穷迷宫(jzoj 3924)

无穷迷宫

jzoj 3924

题目大意

有一个n*m的迷宫,有墙(#),路(.),和你的位置(S),这个迷宫会复制无数份拼在一起,问你能不能不停地走下去

输入样例

2
5 4
##.#
##S#
#..#
#.##
#..#
5 4
##.#
##S#
#..#
..#.
#.##

输出样例

Yes
No	

样例解释

第一组测试数据中,机器人不断沿着路径向上走即可。
第二组测试数据中,机器人无论向哪个方向走都会是死路。

数据范围

50% 的数据: 1 N , M 50. 1 \leqslant N, M \leqslant 50.
100% 的数据: 1 N , M 1500 1 T 4. 1 \leqslant N, M \leqslant 1500,1 \leqslant T \leqslant 4.

解题思路

因为我们不能尝试不停的走下去,那我们想一下:
如果我们能做到不同迷宫的同一位置,那我们就可以用同样的方式再走到另一个迷宫的同一位置,那就是可以无限得走下去
那我们dfs时,保存在迷宫内的位置,也要保存对于第一个迷宫的位置,这样就可以判断是不是不同迷宫的统一个位置

代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
int t, n, m, x, y, ans, f[2000][2000][5];
char a[2000][2000];
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
int sx(int x)
{
	return (x + n - 1) % n + 1;
}
int sy(int y)
{
	return (y + m - 1) % m + 1;
}
void dfs(int x, int y, int lx, int ly)//xy是%了的lxly是没%的
{
	if (f[x][y][0] && (f[x][y][1] != lx || f[x][y][2] != ly))//之前是否在别的迷宫到过这个位置
	{
		ans = 1;
		return;
	}
	f[x][y][0] = 1;
	f[x][y][1] = lx;
	f[x][y][2] = ly;
	for (int i = 0; i < 4 && !ans; ++i)
		if (a[sx(x + dx[i])][sy(y + dy[i])] != '#' && (!f[sx(x + dx[i])][sy(y + dy[i])][0] || f[sx(x + dx[i])][sy(y + dy[i])][1] != lx + dx[i] || f[sx(x + dx[i])][sy(y + dy[i])][2] != ly + dy[i]))//不是同一个迷宫,或没到过且不是墙
			dfs(sx(x + dx[i]), sy(y + dy[i]), lx + dx[i], ly + dy[i]);
}
int main()
{
	scanf("%d", &t);
	while(t--)
	{
		memset(f, 0, sizeof(f));
		ans = 0;
		scanf("%d %d", &n, &m);
		for (int i = 1; i <= n; ++i)
			for (int j = 1; j <= m; ++j)
			{
				cin>>a[i][j];
				if (a[i][j] == 'S')
					x = i, y = j;
			}
		dfs(x, y, x, y);
		if (ans) printf("Yes\n");
		else printf("No\n");
	}
	return 0;
}
发布了334 篇原创文章 · 获赞 57 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/ssllyf/article/details/104328452
今日推荐