公式

D - Snuke Maze 解説 by en_translator


Consider a directed graph \(G\) whose vertices are the cells. For all pairs of cells \((i_1,j_1),(i_2,j_2)\), add an edge from \((i_1,j_1)\) to \((i_2,j_2)\).

  • \((i_1,j_1)\) is adjacent to \((i_2,j_2)\) sharing a side
  • \((i_1,j_1)\) has one of s, n, u, k, and e written on it.
  • If s is written on \((i_1,j_1)\), then n is written on \((i_2,j_2)\).
  • If n is written on \((i_1,j_1)\), then u is written on \((i_2,j_2)\).
  • \(\vdots\)
  • If e is written on \((i_1,j_1)\), then s is written on \((i_2,j_2)\).

Then, the conditions in the problem statement are satisfied if and only if there is a path from \((1,1)\) to \((H,W)\) on \(G\). Thus, by performing DFS (Depth-First Search) or BFS (Breadth-First Search) on \(G\), the problem can be solved in a total of \(O(HW)\) time.

Sample code (C++):

#include<bits/stdc++.h>

using namespace std;

const vector<int> dx = {0, 0, 1, -1};
const vector<int> dy = {1, -1, 0, 0};

int main() {
    int h, w;
    cin >> h >> w;
    vector<string> s(h);
    for (int i = 0; i < h; i++) cin >> s[i];
    if (s[0][0] != 's') {
        cout << "No" << endl;
        return 0;
    }
    vector<char> next(256);
    next['s'] = 'n';
    next['n'] = 'u';
    next['u'] = 'k';
    next['k'] = 'e';
    next['e'] = 's';
    vector seen(h, vector<bool>(w));
    auto dfs = [&](auto &dfs, int i, int j) -> void {
        seen[i][j] = true;
        for (int k = 0; k < 4; k++) {
            int ni = i + dx[k];
            int nj = j + dy[k];
            if (ni < 0 or ni >= h or nj < 0 or nj >= w) continue;
            if (s[ni][nj] != next[s[i][j]]) continue;
            if (seen[ni][nj]) continue;
            dfs(dfs, ni, nj);
        }
    };
    dfs(dfs, 0, 0);
    cout << (seen[h - 1][w - 1] ? "Yes" : "No") << endl;
}

投稿日時:
最終更新: