Game Theory (HackerRank) : Misère Nim
問題
Programming Problems and Competitions :: HackerRank
Nimゲームとほぼ同じだが、最後の石を取ったほうが負け(動かせなくなった方の勝ち)であるところが違う。
解法
Nim - sigma425のブログ
↑より分かりやすそうな説明
(1, 1, 1, ...)
まず、の山だけしかなくて、それが奇数個の場合、これは負けの状態である。逆に偶数個なら勝ちの状態である。
(2, 1, 1, ...)
次にである山が1つだけあり、残りが全くないかだとする。である山を崩してである山の遇奇を自由にいじれるので、これは勝ちの状態である。
普通にゲームをしていればこの状態は避けられないので、この状態で手番が回ってきた方の勝ちだと分かる。
上のような状態を奪うにはどうすればいいだろうか。
普通のNimと同じような戦法を取ってみる。
の状態で回ってきた方が、常にXOR=0の状態を相手に渡し続けていく。
上で説明した 2, 1, 1, ... のような状態はXOR>0だから、XOR>0で回ってきたプレイヤーはこの状態を奪えるので、ここでNim戦法をやめて遇奇をいじれば勝てる。
全ての山が最初から1の時だけ勝敗条件が変わることに気をつけなければいけない。
実装
#define _CRT_SECURE_NO_WARNINGS #define _USE_MATH_DEFINES #include <bits/stdc++.h> using namespace std; #define int long long int T, N, S[100]; signed main() { cin >> T; for (int tc = 0; tc < T; tc++) { cin >> N; int ma = 0, x = 0; for (int i = 0; i < N; i++) { cin >> S[i]; x ^= S[i]; ma = max(ma, S[i]); } if (ma < 2) puts((N&1) ? "Second" : "First"); else puts(x ? "First" : "Second"); } return 0; }