KCS Irregular Contest #001 D
kagamizさんが主催のコンテストに出てみた。
http://kcs.miz-miz.biz/contest/1006/problem_list
制約条件
石の個数の和が10^6以下とか
方針
全ての山がサイズ1だったら、偶数なら先手が勝ちで奇数なら後手が勝ち。
サイズ2以上の山が一つあり、残りが全てサイズ1だったら、
先手はサイズ2以上の山から石を全部取るか1個残すかを選べるので、残す山の個数を偶数奇数選べる。
すなわち先手必勝。
サイズ2以上の山があるときは、全てのxorを取って、0に等しければ後手が必ず勝てる。
なぜかというと、サイズ2以上の山があり、xor = 0であるときは、サイズ2以上の山は必ず2つ以上ある。
なので、通常のNimと同じように、先手の手に対してxor = 0に戻す手が取れる。
これをやっていって、先手の手でサイズ2の山が残り1個になったら、上の考察に帰着して後手が勝つ。
ソースコード
int n; string s; int main(){ cin >> n >> s; int cnt = 0, one = 0, x = 0; vi v; rep(i, n){ if(s[i] == '#'){ if(cnt) v.pb(cnt); cnt = 0; } else cnt++; } if(cnt) v.pb(cnt); if(v.size() == 0 || v[0] == n){ cout << "Smith" << endl; return 0; } rep(i, v.size()){ if(v[i] == 1) one++; x ^= v[i]; } cout << (x == 0 && one != v.size() || one == v.size() && x == 1 ? "Pastel" : "Smith") << endl; return 0; }