題意:給你乙個nxm的迷宮g(x,y範圍是0~n - 1和0~m - 1),『#』不能走,『.』可以走,'s'作為起點,現在將迷宮擴充套件成無窮大,擴充套件方法是:任意乙個(x, y)位置的字元c = g(x % n, y % m),現在問你可不可以從起點處走到無窮遠處。
例子:
原始迷宮5x5為中間的黃色區域,標紅色的位置的座標為(-2, -4), 而 (-2) % 5 = 3, (-4) % 5 = 1, 所以(-2, 4)位置處,應該和g(3, 1)相同,所以為s。
思路:對於乙個位置a(x, y)如果能夠走到另乙個位置b(p, q), a≠b,並滿足a和b在對應的nxm圖中的相對位置相同(意思是:p % n = x % n, q % m = y % m),那麼不斷重複這個過程,就一定能走到無窮遠處。所以考慮從起點(位於原圖中,擴充套件的圖中的其他s看成是『.』)開始dfs(此處是flood fill),一旦兩次都遍歷到了原圖上的同一位置,並且這兩次遍歷到的點不同,那麼說明可以走到無窮遠處,否則不能。
注意紅色部分:假設兩次遍歷到的點為(x,y)和(p,q), 那麼遍歷到原圖上的同一位置指的是p % n = x % n, q % m = y % m(是就相對位置而言的)
一開始我是每遍歷到乙個點(x, y)就對原圖上的(x % n, y % m)標記訪問過,然後在後面的遍歷過程中一旦發現乙個位置(p, q)有(p % n, q % m)已經被訪問過,那麼就認為能夠走到無窮遠,這是錯的,因為有可能(x, y)和(p, q)是同乙個點。
由於模運算的不可逆,意思就是說,如果只是簡單的在訪問到(x,y)時,對(x % n,y % m)標記已訪問,那麼在下一次搜尋到某點(p, q)時就算(p % n,q % m)恰好為(x, y)標記過的地方,也不能肯定(p, q)和(x, y)不是同一點,所以有必要對於原圖中的每乙個位置(u, v)儲存一下第一次訪問到它(指x % n = u, y % m = v)的座標(x, y)。
由於涉及到負數取模,所以還得自己寫一下取模函式。
#include#includeusing namespace std;
const int n = 1510;
int n, m;
char g[n][n];
int st[n][n][3]; // st[u][v][0~2]分別表示:是否訪問過,x和y
int dx = , dy = ;
int mod(int a, int b)
int dfs(int x, int y)
st[ma][mb][0] = 1, st[ma][mb][1] = a, st[ma][mb][2] = b;
if(dfs(a, b)) return 1;
}return 0;
}int main()
st[x][y][0] = 1, st[x][y][1] = x, st[x][y][2] = y;
if(dfs(x, y)) cout << "yes" << endl;
else cout << "no" << endl;
}return 0;
}
P1363 幻象迷宮
那麼,我們可以很清晰的意識到,如果可以從點 x,y 出發,達到比如 x,y 或者 x,y x,y x m,y n 假設寬m高n 就可以從這個點再次達到相同的點 即可以從 x,y 出發,達到 i,j 且 i n x j m y。一直這麼走下去。那就搜好了。開乙個三維vis陣列第一維記錄有無被訪問,第二...
洛谷P1363 幻象迷宮
題意 給出乙個迷宮,判斷能不能走到距離無限遠的地方 分析 本來想複製成3 3的圖然後走的,但是空間有點困難。後面改成了2 2的圖,不過我開了3 3的圖的空間還是過了。解法 dfs include include define re register using namespace std const...
洛谷P1363幻象迷宮
幻象迷宮可以認為是無限大的,不過它由若干個n m的矩陣重複組成。矩陣中有的地方是道路,用 表示 有的地方是牆,用 表示。lhx和wd所在的位置用 s 表示。也就是對於迷宮中的乙個點 x,y 如果 x mod n,y mod m 是 或者 s 那麼這個地方是道路 如果 x mod n,y mod m ...