なるほど。
https://yukicoder.me/problems/no/3120
問題
Nimの変形ゲームのinteractive問題である。
2手目以降は、直前の相手の手番で選んだ値以下の値しか選べない、という条件を加えたうえでNimに勝利せよ。
解法
山の石の数のxorが0か非0かで勝者が確定するのは、普通のNimと同じ。
xorが0であった状態で相手がK減らすことを選択した場合、数列中にLSB(K)のbitが立っている山が1つはあることになるので、自分の手番でLSB(K)を減らすことができる。
よってxorが0の状態で後手を取れれば後手必勝。
int N; int A[10101]; void solve() { int i,j,k,l,r,x,y; string s; cin>>N; int nim=0; FOR(i,N) { cin>>A[i]; nim^=A[i]; } int K=1<<20; if(nim) { cout<<"First"<<endl; while(1) { nim=0; FOR(i,N) nim^=A[i]; x=1; FOR(j,100) if(nim&(1<<j)) { x=1<<j; break; } y=0; FOR(i,N) if(A[i]>=A[y]) y=i; cout<<y+1<<" "<<x<<endl; A[y]-=x; cin>>x; if(x) return; cin>>x>>y; A[x-1]-=y; cin>>x; if(x) return; } } else { cout<<"Second"<<endl; while(1) { cin>>x>>y; A[x-1]-=y; cin>>x; if(x) return; nim=0; FOR(i,N) nim^=A[i]; x=1; FOR(j,100) if(nim&(1<<j)) { x=1<<j; break; } y=0; FOR(i,N) if(A[i]>=A[y]) y=i; cout<<y+1<<" "<<x<<endl; A[y]-=x; cin>>x; if(x) return; } } }
まとめ
シンプルな問題設定で良い感じ。