結果

問題 No.3504 Insert Maze
コンテスト
ユーザー Naru820
提出日時 2026-03-17 21:52:42
言語 C++23
(gcc 15.2.0 + boost 1.89.0)
コンパイル:
g++-15 -O2 -lm -std=c++23 -Wuninitialized -DONLINE_JUDGE -o a.out _filename_
実行:
./a.out
結果
AC  
実行時間 818 ms / 2,000 ms
コード長 3,305 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 1,521 ms
コンパイル使用メモリ 166,300 KB
実行使用メモリ 132,736 KB
最終ジャッジ日時 2026-04-17 19:41:25
合計ジャッジ時間 35,102 ms
ジャッジサーバーID
(参考情報)
judge3_1 / judge2_1
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 85
権限があれば一括ダウンロードができます

ソースコード

diff #
raw source code

// gemini 3.1pro
#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main() {
    // 入出力の高速化
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int H, W;
    if (!(cin >> H >> W)) return 0;
    
    vector<string> grid(H);
    for (int i = 0; i < H; i++) {
        cin >> grid[i];
    }

    // 4つの状態 × H × W の最大ノード数
    int max_nodes = 4 * H * W;
    // 距離配列(-1で未訪問を管理)
    vector<int> dist(max_nodes, -1);
    // 高速なキュー(vectorで代用)
    vector<int> q(max_nodes);
    int head = 0, tail = 0;

    // 次の状態をキューに追加するラムダ式
    auto push = [&](int d, int ntype, int nr, int nc) {
        // 範囲外チェック
        if (nr < 0 || nc < 0) return;
        if (ntype == 0 && (nr >= H || nc >= W)) return;
        if (ntype == 1 && (nr >= H - 1 || nc >= W)) return;
        if (ntype == 2 && (nr >= H || nc >= W - 1)) return;
        if (ntype == 3 && (nr >= H - 1 || nc >= W - 1)) return;
        
        // 通常状態の場合は壁をチェック
        if (ntype == 0 && grid[nr][nc] == '#') return;
        
        int v = ntype * H * W + nr * W + nc;
        if (dist[v] == -1) {
            dist[v] = d + 1;
            q[tail++] = v;
        }
    };

    // スタート地点 (タイプ0, 0行目, 0列目)
    int start_id = 0 * H * W + 0 * W + 0;
    dist[start_id] = 0;
    q[tail++] = start_id;

    while (head < tail) {
        int u = q[head++];
        int type = u / (H * W);
        int rem = u % (H * W);
        int r = rem / W;
        int c = rem % W;
        int d = dist[u];

        if (type == 0) { // EE (通常マス)
            if (r == H - 1 && c == W - 1) {
                cout << d << "\n";
                return 0;
            }
            // そのまま移動
            push(d, 0, r + 1, c);
            push(d, 0, r - 1, c);
            push(d, 0, r, c + 1);
            push(d, 0, r, c - 1);
            // 横ハイウェイ(OE)へ降りる
            push(d, 1, r, c);
            push(d, 1, r - 1, c);
            // 縦ハイウェイ(EO)へ降りる
            push(d, 2, r, c);
            push(d, 2, r, c - 1);
        } else if (type == 1) { // OE (横ハイウェイ)
            // 通常マスへ戻る
            push(d, 0, r, c);
            push(d, 0, r + 1, c);
            // ハイウェイ上を横移動
            push(d, 1, r, c - 1);
            push(d, 1, r, c + 1);
            // 交差点(OO)へ移動
            push(d, 3, r, c);
            push(d, 3, r, c - 1);
        } else if (type == 2) { // EO (縦ハイウェイ)
            // 通常マスへ戻る
            push(d, 0, r, c);
            push(d, 0, r, c + 1);
            // ハイウェイ上を縦移動
            push(d, 2, r - 1, c);
            push(d, 2, r + 1, c);
            // 交差点(OO)へ移動
            push(d, 3, r, c);
            push(d, 3, r - 1, c);
        } else if (type == 3) { // OO (交差点)
            // ハイウェイへ抜ける
            push(d, 1, r, c);
            push(d, 1, r, c + 1);
            push(d, 2, r, c);
            push(d, 2, r + 1, c);
        }
    }

    // どうやっても到達できない場合
    cout << -1 << "\n";
    return 0;
}
0