結果
問題 |
No.3120 Lower Nim
|
ユーザー |
|
提出日時 | 2025-04-24 14:52:31 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
WA
|
実行時間 | - |
コード長 | 2,429 bytes |
コンパイル時間 | 2,020 ms |
コンパイル使用メモリ | 195,472 KB |
実行使用メモリ | 25,972 KB |
平均クエリ数 | 2233.55 |
最終ジャッジ日時 | 2025-04-24 14:52:42 |
合計ジャッジ時間 | 9,568 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 1 |
other | AC * 39 WA * 4 |
ソースコード
#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]; } // ∑A_i ≤ 10000 なので、初期 K は 10001 に設定 int K = 10001; // 現在の山の XOR を計算 auto calcXor = [&](){ int s = 0; for(int v : A) s ^= v; return s; }; // 初期 XOR で先手・後手決定 int S = calcXor(); bool isFirst = (S != 0); cout << (isFirst ? "First\n" : "Second\n") << flush; bool ourTurn = isFirst; while(true){ int i, x, ret; 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; // 1) 通常の Nim の要領で XOR を 0 に戻せるならその手 if(S != 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; } } } } // 2) 上記ができない場合は、まず可能なら上限 K を丸取り if(move_i == -1){ for(int j = 0; j < N; j++){ if(A[j] >= K){ move_i = j; move_x = K; break; } } } // 3) それもできなければ 1 個だけ取る if(move_i == -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; }