結果

問題 No.3120 Lower Nim
ユーザー keigo kuwata
提出日時 2025-04-24 14:50:02
言語 C++17
(gcc 13.3.0 + boost 1.87.0)
結果
WA  
実行時間 -
コード長 2,288 bytes
コンパイル時間 2,232 ms
コンパイル使用メモリ 194,796 KB
実行使用メモリ 26,048 KB
平均クエリ数 2371.84
最終ジャッジ日時 2025-04-24 14:50:13
合計ジャッジ時間 10,370 ms
ジャッジサーバーID
(参考情報)
judge1 / judge2
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 1
other AC * 39 WA * 4
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
using namespace std;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int N;
    cin >> N;
    vector<int> A(N);
    for(int i = 0; i < N; i++){
        cin >> A[i];
    }

    // 初期の K は ∑A_i ≤ 10000 より十分
    int K = 10001;

    // 山の XOR を計算するラムダ
    auto calcXor = [&](){
        int x = 0;
        for(int v : A) x ^= v;
        return x;
    };

    // 初期 XOR で先手・後手を決定
    int S = calcXor();
    bool isFirst = (S != 0);

    if(isFirst){
        cout << "First\n" << flush;
    } else {
        cout << "Second\n" << flush;
    }

    bool ourTurn = isFirst;
    while(true){
        int ret, i, x;

        if(!ourTurn){
            // ジャッジ(相手)の手番の読み込み
            cin >> i >> x;
            cin >> ret;
            if(ret == -1){
                // 我々の敗北
                return 0;
            }
            // 継続なら状態更新
            --i;
            A[i] -= x;
            K = x;
        }

        // 我々の手番
        S = calcXor();
        int move_i = -1, move_x = 1;

        if(S != 0){
            // XOR を 0 に戻せる取りを探す
            for(int j = 0; j < N; j++){
                int a = A[j];
                int t = a ^ S;
                if(t < a){
                    int r = a - t;
                    if(r <= K){
                        move_i = j;
                        move_x = r;
                        break;
                    }
                }
            }
        }

        if(move_i == -1){
            // XOR=0 のとき、あるいは調整手が取れないときは常に 1 個だけ取る
            for(int j = 0; j < N; j++){
                if(A[j] > 0){
                    move_i = j;
                    move_x = 1;
                    break;
                }
            }
        }

        // 手を出力
        A[move_i] -= move_x;
        cout << (move_i + 1) << " " << move_x << "\n" << flush;

        // ジャッジからの返り値
        cin >> ret;
        if(ret != 0){
            // ret == 1 なら勝利、ret == -1 なら敗北
            return 0;
        }
        K = move_x;
        ourTurn = false;
    }

    return 0;
}
0