無窮迷宮 & 幻象迷宮

無窮迷宮

&\&

幻象迷宮

題目鏈接:

1. 無窮迷宮:jzoj 3924jzoj\ 3924
2. 幻象迷宮:luogu 1363luogu\ 1363

無盡迷宮:

題目

傳說有一個無窮大的迷宮,這個迷宮實際上是將一個長方形的迷宮無限複製得到的。長方形的迷宮有NNMM列個格子。每個格子要麼是空地,要麼是牆。大迷宮的每個格子(x,y)(x, y)和格子(x mod N,y mod M)(x\ mod\ N, y\ mod\ M)是相同的。(x mod Nx\ mod\ Nxx 除以 NN 的餘數)
一個機器人現在站在位置(x,y)(x, y)的格子。每一步,機器人可以移動到上下左右相鄰的空地。而且它從不會走到已經走過的位置。請你判斷機器人能否在迷宮中無窮地走下去。

輸入

第一行,一個整數TT,表示有TT組測試數據。
接下來若干行,分別描述每組數據。
每組數據的第一行是兩個整數NN , MM .
接下來是NN行,每行是MM個字符的字符串,描述一個長方形迷宮的所有格子。空地用.‘.’表示,牆用#‘\#’表示,機器人所在位置用S‘S’表示。

輸出

輸出TT行,每行一個字符串,依次表示每組測試數據的結果。如果機器人能無窮走下去輸出Yes”Yes”,否則輸出No”No”

樣例解釋(樣例在下面)

第一組測試數據中,機器人不斷沿着路徑向上走即可。
第二組測試數據中,機器人無論向哪個方向走都會是死路。

數據範圍

50% ⁣50\%\! 的數據:1 ⁣<= ⁣N,M ⁣ ⁣<= ⁣50.1\! <=\! N, M\! \!<=\! 50.
100% ⁣100\%\! 的數據:1 ⁣<= ⁣N,M ⁣<= ⁣15001 ⁣<= ⁣T ⁣<= ⁣4.1 \!<= \!N, M \!<=\! 1500,1\! <=\! T\! <=\! 4.

幻想迷宮:

題目背景

(喵星人LHXLHXWDWD同心協力擊退了汪星人的入侵,不幸的是,汪星人撤退之前給它們製造了一片幻象迷宮。)

W ⁣DW\!D:嗚嗚,腫麼辦啊……

LH ⁣XLH\!Xmomo...momo...我們一定能走出去的!

W ⁣DW\!D:嗯,+U ⁣ ⁣+ ⁣U+U\!\!+\!U!

題目

幻象迷宮可以認爲是無限大的,不過它由若干個NMN*M的矩陣重複組成。矩陣中有的地方是道路,用.'.'表示;有的地方是牆,用#'\#'表示。LH ⁣XLH\!XW ⁣DW\!D所在的位置用S'S'表示。也就是對於迷宮中的一個點(x,y)(x,y),如果(x mod n,y mod m)(x\ mod\ n,y\ mod\ m).'.'或者S'S',那麼這個地方是道路;如果(x mod n,y mod m)(x\ mod\ n,y\ mod\ m)#'\#',那麼這個地方是牆。LH ⁣XLH\!XW ⁣DW\!D可以向上下左右四個方向移動,當然不能移動到牆上。

請你告訴LH ⁣XLH\!XW ⁣DW\!D,它們能否走出幻象迷宮(如果它們能走到距離起點無限遠處,就認爲能走出去)。如果不能的話,LH ⁣XLH\!X就只好啓動城堡的毀滅程序了……當然不到萬不得已,他不想這麼做。。。

輸入

輸入包含多組數據,以EOFEOF結尾。

每組數據的第一行是兩個整數NNMM

接下來是一個NMN*M的字符矩陣,表示迷宮裏(0,0)(0,0)(n ⁣ ⁣1,m ⁣ ⁣1)(n\!-\!1,m\!-\!1)這個矩陣單元。

輸出

對於每組數據,輸出一個字符串,YesYes或者NoNo

數據範圍

對於30%30\%的數據,N,M ⁣<= ⁣20N,M\!<=\!20
對於50%50\%的數據,N,M ⁣<= ⁣100N,M\!<=\!100
對於100%100\%的數據,N,M ⁣<= ⁣1500N,M\!<=\!1500,每個測試點不超過1010組數據

共同:(樣例在這裏)

樣例輸入

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

樣例輸出

Yes
No

思路與代碼:

思路

這道題就是dfsdfs,一點都不簡單的dfsdfs

不能把圖複製幾倍什麼的,因爲會有一些噁心的數據,比如這個:

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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章