題目鏈接:
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;
}