結果

問題 No.3120 Lower Nim
ユーザー keigo kuwata
提出日時 2025-04-24 14:40:06
言語 Python3
(3.13.1 + numpy 2.2.1 + scipy 1.14.1)
結果
TLE  
実行時間 -
コード長 2,232 bytes
コンパイル時間 405 ms
コンパイル使用メモリ 12,288 KB
実行使用メモリ 27,776 KB
平均クエリ数 1139.70
最終ジャッジ日時 2025-04-24 14:40:41
合計ジャッジ時間 34,772 ms
ジャッジサーバーID
(参考情報)
judge1 / judge5
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample -- * 1
other AC * 24 WA * 5 TLE * 7 -- * 7
権限があれば一括ダウンロードができます

ソースコード

diff #

#!/usr/bin/env python3
import sys
input = sys.stdin.readline

def main():
    N = int(input())
    A = list(map(int, input().split()))
    # 全体 XOR を計算
    total_xor = 0
    for a in A:
        total_xor ^= a

    # 初手の選択
    if total_xor != 0:
        print("First")
        our_turn = True
    else:
        print("Second")
        our_turn = False
    sys.stdout.flush()

    # K は直前に取った石の数。初期は十分大きくしておく
    K = 10**9

    while True:
        if not our_turn:
            #------ judge の手を読む ------
            line = input().split()
            if not line:
                return
            i, x = map(int, line)
            ret = int(input())
            if ret == -1:
                # 敗北
                return
            # 状態更新
            A[i-1] -= x
            K = x
            our_turn = True
        else:
            #------ 自分の手 ------
            # 最新の全体 XOR を再計算
            total_xor = 0
            for a in A:
                total_xor ^= a

            # 勝ち筋:XOR を 0 にする取り
            move_i = move_x = None
            if total_xor != 0:
                for idx, a in enumerate(A):
                    target = a ^ total_xor
                    # target < a かつ 取り分 (a-target) ≤ K となる山を探す
                    if target < a and (a - target) <= K:
                        move_i = idx
                        move_x = a - target
                        break

            # losing 状態か、安全な取りが見つからない場合は最低限 1 石だけ取る
            if move_x is None:
                for idx, a in enumerate(A):
                    if a > 0:
                        move_i = idx
                        move_x = min(a, K)
                        break

            # 手を出力
            print(move_i+1, move_x)
            sys.stdout.flush()
            A[move_i] -= move_x

            ret = int(input())
            if ret == 1 or ret == -1:
                # 勝利 or 惨敗
                return

            # 更新
            K = move_x
            our_turn = False

if __name__ == "__main__":
    main()
0