题目链接:
1. 无穷迷宫:
2. 幻象迷宫:
题目
传说有一个无穷大的迷宫,这个迷宫实际上是将一个长方形的迷宫无限复制得到的。长方形的迷宫有行列个格子。每个格子要么是空地,要么是墙。大迷宫的每个格子和格子是相同的。( 指 除以 的余数)
一个机器人现在站在位置的格子。每一步,机器人可以移动到上下左右相邻的空地。而且它从不会走到已经走过的位置。请你判断机器人能否在迷宫中无穷地走下去。
输入
第一行,一个整数,表示有组测试数据。
接下来若干行,分别描述每组数据。
每组数据的第一行是两个整数 , .
接下来是行,每行是个字符的字符串,描述一个长方形迷宫的所有格子。空地用表示,墙用表示,机器人所在位置用表示。
输出
输出行,每行一个字符串,依次表示每组测试数据的结果。如果机器人能无穷走下去输出,否则输出。
样例解释(样例在下面)
第一组测试数据中,机器人不断沿着路径向上走即可。
第二组测试数据中,机器人无论向哪个方向走都会是死路。
数据范围
的数据:
的数据:
题目背景
(喵星人和同心协力击退了汪星人的入侵,不幸的是,汪星人撤退之前给它们制造了一片幻象迷宫。)
:呜呜,肿么办啊……
:我们一定能走出去的!
:嗯,
题目
幻象迷宫可以认为是无限大的,不过它由若干个的矩阵重复组成。矩阵中有的地方是道路,用表示;有的地方是墙,用表示。和所在的位置用表示。也就是对于迷宫中的一个点,如果是或者,那么这个地方是道路;如果是,那么这个地方是墙。和可以向上下左右四个方向移动,当然不能移动到墙上。
请你告诉和,它们能否走出幻象迷宫(如果它们能走到距离起点无限远处,就认为能走出去)。如果不能的话,就只好启动城堡的毁灭程序了……当然不到万不得已,他不想这么做。。。
输入
输入包含多组数据,以结尾。
每组数据的第一行是两个整数、。
接下来是一个的字符矩阵,表示迷宫里到这个矩阵单元。
输出
对于每组数据,输出一个字符串,或者。
数据范围
对于的数据,
对于的数据,
对于的数据,,每个测试点不超过组数据
样例输入
2
5 4
##.#
##S#
#..#
#.##
#..#
5 4
##.#
##S#
#..#
..#.
#.##
样例输出
Yes
No
思路
这道题就是,一点都不简单的。
不能把图复制几倍什么的,因为会有一些恶心的数据,比如这个:
1
5 7
S#..#.#
#..#..#
#.#..#.
#.#.#..
..#.#.#
这个还小,但是按这种方法,就会把你卡死。
所以要用另外的方法,我们可以记录这个人在矩阵中的哪个位置,又在整个迷宫中的哪一个位置。如果这个人现在走到的位置之前走到过(指矩阵中),而且第一次经过和第二次经过的真实位置不一样(指整个迷宫中),那么就可以无限走了。
(因为形成了循环,而要真实位置不要相同,是因为有可能他们只是在两个点之间反复横跳罢了)
代码
#include<cstdio>
#include<cstring>
#include<iostream>
#define rr register
using namespace std;
struct node{
int x, y, in;
}in[1501][1501];
int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
int T, n, m, rx, ry, ans;
bool a[1501][1501];
char c;
bool dfs(int x, int y, int real_x, int real_y) {
if (in[x][y].in && (in[x][y].x != real_x || in[x][y].y != real_y)) {//形成循环
ans = 1;
return 0;
}
in[x][y] = (node){real_x, real_y, 1};//记录
for (int i = 0; i < 4; i++) {//方向
if(a[(x + dx[i] + n) % n][(y + dy[i] + m) % m]) {//能走
if(in[(x + dx[i] + n) % n][(y + dy[i] + m) % m].x != real_x + dx[i] ||
in[(x + dx[i] + n) % n][(y + dy[i] + m) % m].y != real_y + dy[i] ||
!in[(x + dx[i] + n) % n][(y + dy[i] + m) % m].in)
//没有走过这个点
dfs((x + dx[i] + n) % n, (y + dy[i] + m) % m, real_x + dx[i], real_y + dy[i]);
}
}
return 0;
}
int main() {
while (cin >> n >> m) {
memset(in, 0, sizeof(in));//初始化
memset(a, 0, sizeof(a));
scanf("%d %d", &n, &m);//读入
for (rr int i = 0; i < n; i++)
for (rr int j = 0; j < m; j++) {
c = getchar();
while (c != '.' && c != 'S' && c != '#') c = getchar();//读入地图
if (c == '.' || c == 'S') {//不是障碍物
a[i][j] = 1;
if (c == 'S') {//是机器人的位置
rx = i;
ry = j;
}
}
}
ans = 0;//初始化
dfs(rx, ry, rx, ry);//dfs
if (ans) printf("Yes\n");//可以
else printf("No\n");//不可以
}
return 0;
}