HDU_1850_nim游戏
Posted Jason333
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU_1850_nim游戏相关的知识,希望对你有一定的参考价值。
Being a Good Boy in Spring Festival
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 6842 Accepted Submission(s):
4144
春节回家 你能做几天好孩子吗
寒假里尝试做做下面的事情吧
陪妈妈逛一次菜场
悄悄给爸爸买个小礼物
主动地 强烈地 要求洗一次碗
某一天早起 给爸妈用心地做回早餐
如果愿意 你还可以和爸妈说
咱们玩个小游戏吧 ACM课上学的呢~
下面是一个二人小游戏:桌子上有M堆扑克牌;每堆牌的数量分别为Ni(i=1…M);两人轮流进行;每走一步可以任意选择一堆并取走其中的任意张牌;桌子上的扑克全部取光,则游戏结束;最后一次取牌的人为胜者。
现在我们不想研究到底先手为胜还是为负,我只想问大家:
——“先手的人如果想赢,第一步有几种选择呢?”
[定理1]:对于任何一个S态,总能从一堆火柴中取出若干个使之成为T态。
证明:
若有n堆火柴,每堆火柴有A(i)根火柴数,那么既然现在处于S态,
c = A(1) xor A(2) xor … xor A(n) > 0;
把c表示成二进制,记它的二进制数的最高位为第p位,则必然存在一个A(t),它二进制的第p位也是1。(否则,若所有的A(i)的第p位都是0,这与c的第p位就也为0矛盾)。
那么我们把x = A(t) xor c,则得到x < A(t).这是因为既然A(t)的第p位与c的第p位同为1,那么x的第p位变为0,而高于p的位并没有改变。所以x < A(t).而
A(1) xor A(2) xor … xor x xor … xor A(n)
= A(1) xor A(2) xor … xor A(t) xor c xor … xor A(n)
= A(1) xor A(2) xor… xor A(n) xor A(1) xor A(2) xor … xor A(n)
= 0
这就是说从A(t)堆中取出 A(t) - x 根火柴后状态就会从S态变为T态。证毕
#include<iostream> #include<cstdio> #include<cstring> #include<stdlib.h> #include<algorithm> #include<cmath> using namespace std; int N[105]; int main() { int m; while(scanf("%d",&m)!=EOF&&m) { int k=0; for(int i=0; i<m; i++) { scanf("%d",&N[i]); k^=N[i]; } if(k==0) printf("0\n"); else { int pos=0; for(int i=0;i<=30;i++) { int tmp=(1<<i); if((tmp&k)>0) pos=i; } //cout<<pos<<endl; int res=0; for(int i=0;i<m;i++) if((N[i]&(1<<pos))>0&&(N[i]^k)<N[i]) res++; printf("%d\n",res); } } return 0; }
以上是关于HDU_1850_nim游戏的主要内容,如果未能解决你的问题,请参考以下文章
HDU1850 Being a Good Boy in Spring Festival(NIM统计)