hdu 4388 Stone Game II 博弈
阿新 • • 發佈:2018-11-05
題目連結:hdu 4388
參考部落格:https://blog.csdn.net/y1196645376/article/details/52143551
題意:
最初有n堆石子,每堆石子個數已知。兩人輪流執行操作,如果當某人無法執行有效操作時即輸。
操作分兩步:
第一步為:選擇其中一堆石子假定石子個數為a,拿走個數不為0的一些石子使得該堆石子剩餘k個並且保證(0 < k < a,k^a < a),^為異或符號。
第二步為:加入一堆新的石子,石子個數為k^a,當然你也可以使用技能使得加入的石子個數變為(2k)^a 。不過每個人每局遊戲只能使用一次技能。
無法執行有效操作即第一步或者第二步無法執行時。
題解:直接看程式碼,裡面有很詳細的註釋。
///先看下題目要求,每次留下的k,滿足 0<k<n && kXORn <n, ///這說明,k只能在n中取二進位制位1的數位,例如n=5(101),那麼k只能是4(100)或者1(001) ///還能知道堆數為2^i時(二進位制只有一位1),不能再分了,已到達邊界了。 ///然後我們假設先考慮一堆石子(n=1),k為這堆石子二進位制位為1的個數,假設為偶數,先手win,也就是n+k為奇數時,先手win ///接著我們考慮有多堆石子(n>1),sum為這堆石子二進位制1的個數,類比於一堆石子,sum+n為奇數時先手win,多堆可以看做單堆單堆的取, ///對了,每位選手還有一次技能加成的機會,我們要清楚的一點的是,這次加成的是用在新加堆上的,並且也不會改變新加堆的二進位制位為1的個數 ///例如n=13(1101),留k=5(101),2*k=1010, k XOR n=1000 ,2*k XOR n=0111,可見,不管用不用技能,新加堆的二進位制位為1的個數的奇偶數還是沒變。over。 /* 例如 n=15(1111) 1 111 先手 1 100 11 後手 1 100 1 1 先手 */ #include<cstdio> #include<algorithm> #include<cstring> #include<string> using namespace std; int main() { int ncase; scanf("%d",&ncase); for(int T=1;T<=ncase;T++) { int n; scanf("%d",&n); int x,sum=0; for(int i=1;i<=n;i++) { scanf("%d",&x); sum+=__builtin_popcount(x); ///庫函式查詢x數字二進位制為1的個數, ///這庫函式有個小坑,前面的下橫線要兩條,艹。 } if((sum+n)&1) printf("Case %d: Yes\n",T); else printf("Case %d: No\n",T); } return 0; }