Nim は、2人でおこなうレクリエーション数学ゲーム(組合せゲーム)の一つです。歴史的には、最初に必勝法が数学的に解決したゲームです。双方が最善をつくす場合、どちらが勝つかは最初の個数の組で決まります。

以下のようなゲームを考えます。

有限個のコインの山を有限個用意する。2人のプレイヤーが山からコインを好きな数ずつ交互に取り合っていく。一度に取るコインは1つの山からとし、最低1個は取らなければいけないとする。最後にコインを取ったプレイヤーを勝ちとする。

コインの山の数を N とし、各山のコインの枚数を A1, …, An とした場合、ビットごとの排他的論理和 xor = A1 ^ A2 ^ ,… , ^ An を考えます。これが xor ≠ 0 ならば先手必勝、S = 0 ならば後手必勝です。

なぜそうなるのでしょうか? コインを取ることで xor ≠ 0 のときは 必ず xor = 0 にすることができます。そして xor = 0 の状態からはどうやっても xor ≠ 0 にしかなりません。コインがなくなったときは xor = 0 なので自分の着手によって xor = 0 の状態を維持することができれば必ず勝つことができます。

Nim の基本問題

石の山が N 個あり、そこには石が A[i] 個あります。先手と後手が交互にひとつの山を選んで 1 個以上の石を取っていき、最初に石を取れなくなったほうが負けです。双方が最善をつくす場合の勝敗を出力してください。

No.524 コインゲーム

No.524 コインゲーム

皿は N 枚あり、1 枚目の皿には 1枚のコインが、i 枚目の皿にはコインが i 枚乗っている。
コインは一度に何枚でも取れるが、1回毎に全て同じ皿から取らなければならない。
コインは必ず一枚以上取る。
コインがない状態で自分の番になったら負け。ゲームは終了し、負けなかったほうが勝ちとなる。
先手である自分が勝つかどうか判定せよ。

入力されるデータ
N
(ただし 1 ≦ N ≦ 2^32)

N が 2^32 と大きいので xor を計算しようとすると時間が足りません。ただ小さな値で実験をしてみると xor の値は N % 4 == 3 のときだけ 0 になり、それ以外のときは非0となります。

Nim と Grundy数

最初の例では取ることができる石の数に上限がありませんでした。もし「1 個以上 k 個以下」という条件がついた場合はどうなるのでしょうか? このようなときに使えるのが Grundy数 です。

Grundy数とはゲームの盤面を非負整数で表したものです。0ならば負け、0以外であれば勝ちです。もし山が 1 つしかなく、自分の番のときに取ることができる石の数が 1 個以上 k 個以下というルールであれば grundy 数は 山にある石の数を k + 1 で割ったときの余りです。山にある残りの石の数を k + 1 で割りきれるように取っていけば必ず勝つことができます。

そしてある盤面のGrundy数はその盤面から遷移できる盤面のGrundy数の集合のMexです。Mexとは集合に含まれない最小の非負整数のことです。集合が空であれば Mex は 0だし、集合が {0, 2, 3} であれば Mex は 1 です。

Nim は盤面の各山のコインの枚数の xor がその盤面のGrundy数になります。よって初期盤面の各山のコインの枚数の xor を計算し、これが 0 以外であれば先手の勝ち、0 であれば後手の勝ちとなります。

No.669 対決!!! 飲み比べ

No.669 対決!!! 飲み比べ

赳也君は今夜、新宿の『思い出横丁』で酒を飲もうと一軒の焼き鳥屋に入りました。そのお店では次のルールで飲み比べ対決が出来るようです。

・店主と赳也君が交互に酒を飲む
・酒の種類はN種類
・自分のターンにおいて、ある1つの種類の酒を選び、それを1~K(整数値) (ml)飲む
・酒を飲めなくなった方が負け

尚、店主も赳也君も非常にお酒に強く「酒を飲めない」⇔「残っているお酒がない」と考えて下さい。

赳也君が先手です。各お酒の量が与えられます。各自最善を尽くすとして、赳也君がこの対決に勝てるかどうかを判定して下さい。

赳也君が勝てるなら「YES」、負けるなら「NO」を出力して下さい。

入力されるデータ
N K
A_1 A_2 … A_N
(ただし、1 ≦ N, K ≦ 1000, 0 ≦ A_i ≦ 1,000,000)

コインが酒に変わっただけです。酒が一種類のときの grundy 数は 残されている量を k + 1 で割ったときの余りであり、複数あるときはそれらの 総xor となります。

No.153 石の山

No.153 石の山

分割されることで石の山の数が増えていきますが、考え方は同じです。

ある盤面の Grundy数 はその盤面から遷移できる盤面の Grundy数 の集合の Mex です。そして Mex とは集合に含まれない最小の非負整数のことです。分割前の Grundy数 は分割後の Grundy数 の排他的論理和です。

Grundy数を計算するときに再帰呼び出しをするのでメモ化で処理の高速化を図っています。