洛谷 1363 幻想迷宫
这是一道不是很难的搜索题,我的第一反应是把矩阵扩大九倍,然后从中间子阵的起点做flood_fill即可。
然后提交,WA,桑心,反思,不解,下样例:终于发现,仅仅扩大九倍是不够的,极端数据可以要求穿过更多的子阵才能到达。
于是,我加了四行代码:
if (nx > n + (n << 1)) nx -= n + (n << 1); if (ny > m + (m << 1)) ny -= m + (m << 1); if (nx < 1) nx = n + (n << 1); if (ny < 1) ny = m + (m << 1);
终于AC:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; int m, n, sx, sy, nx, ny; int dx[] = {0, 0, 1, -1}; int dy[] = {1, -1, 0, 0}; char ch; char c[5000][5000]; bool vis[5000][5000]; bool v[2000][2000]; bool pt; struct node { int x; int y; }cur, fir; void flood_fill(int x, int y) { fir.x = x; fir.y = y; queue <node> Q; Q.push(fir); v[x%n == 0 ? n : x%n][y%m == 0 ? m : y%m] = 1; vis[x][y] = 1; while (!Q.empty()) { cur = Q.front(); Q.pop(); for (int i = 0; i < 4; ++i) { nx = cur.x + dx[i]; ny = cur.y + dy[i]; if (nx > n + (n << 1)) nx -= n + (n << 1); if (ny > m + (m << 1)) ny -= m + (m << 1); if (nx < 1) nx = n + (n << 1); if (ny < 1) ny = m + (m << 1); if (c[nx][ny] == '#' || nx < 1 || ny < 1 || nx > n + (n << 1) || ny > m + (m << 1) || vis[nx][ny]) continue; if (v[nx%n == 0 ? n : nx%n][ny%m == 0 ? m : ny%m] == 1) { pt = true; goto good; } v[nx%n == 0 ? n : nx%n][ny%m == 0 ? m : ny%m] = 1; vis[nx][ny] = 1; fir.x = nx; fir.y = ny; Q.push(fir); } } good:; } int main() { while (cin >> n >> m) { memset(v, false, sizeof(v)); memset(vis, false, sizeof(vis)); for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) { cin >> c[i][j]; if (c[i][j] == 'S') sx = i, sy = j, c[i][j] = '.'; ch = c[i][j]; c[i][j + m] = ch; c[i][j + (m << 1)] = ch; c[i + n][j] = ch; c[i + n][j + m] = ch; c[i + n][j + (m << 1)] = ch; c[i + (n << 1)][j] = ch; c[i + (n << 1)][j + m] = ch; c[i + (n << 1)][j + (m << 1)] = ch; } pt = false; flood_fill(sx + n, sy + m); if (pt) puts("Yes"); else puts("No"); } }