博弈——混合(尼姆)HDU 4388 Stone Game II
阿新 • • 發佈:2018-12-18
1.題目含義:
一共有n堆石子,每堆石子個數用x表示。現在你可以選擇一堆移除某些石子,但要剩餘k個石子,確保k在[1,n-1]這個區間內。
移除石子後,還要加入一些石子,加入石子的個數為:k^x,當然你也可以使用技能使得加入的石子個數變為(2k)^x。不過每個人每局遊戲只能使用一次技能。問最後先手是否可以取得勝利,可以的話輸出Yes,否則輸出No。
2.思路:
2.1 先不考慮技能,其實每輪的操作就是將一個大小為x的堆分成大小為k和(x^k)的堆,這裡很關鍵的一點是要能發現分堆之前x中二進位制1的個數與分堆之後k與(x^k)的二進位制1個數和的奇偶性是相同的。這個結論可以這樣想,考慮x的某一位p,就會有四種情況:
2.1.1. 如果x的第p位為1且k的第p位也為1,那麼(x^k)的第p位就是0. ——開始1的個數為2,拆分後1的個數還是2
2.1.2. 如果x的第p位為1且k的第p位也為0,那麼(x^k)的第p位就是1.——開始1的個數為1,拆分後1的個數還是1
2.1.3. 如果x的第p位為0且k的第p位也為1,那麼(x^k)的第p位就是1.——開始1的個數為1,拆分後1的個數還是1
2.1.4. 如果x的第p位為0且k的第p位也為0,那麼(x^k)的第p位就是0.——開始1的個數為1,拆分後1的個數還是0
可以發現無論哪種情況,奇偶性都不會發生變化,這是本題的關鍵。
2.2考慮N堆的情況,總共可操作次數為奇數先手贏,否則先手輸。
2.3考慮技能的情況,技能不會增加1的個數
2.4另外考慮遊戲什麼時候結束,很顯然當一個堆x的二進位制1的個數只有1個的時候,就不能再分了,那麼如果所有的堆都這樣,遊戲就結束了。
2.5 當n+cnt(n堆石子二進位制1的個數)為奇數時,先手取得勝利。
#include<iostream> #include<algorithm> #include<cstring> #include<cmath> #include<cstdio> using namespace std; int t; int count(int num) { int cnt=0; while(num) { cnt=cnt+num&1; num>>=1; } return cnt; } int main() { int j; int num; cin>>t; for(j=1;j<=t;j++) { int n; int ans=0; cin>>n; for(int i=0;i<n;i++) { cin>>num; ans=ans+count(num); } ans=ans+n; if(ans&1) cout<<"Case "<<j<<": "<<"Yes"<<endl; else cout<<"Case "<<j<<": "<<"No"<<endl; } return 0; }