xtuoj 1235 CQRXLB(博弈论)
CQRXLB |
||
Accepted : 19 | Submit : 40 | |
Time Limit : 1000 MS | Memory Limit : 65536 KB |
CQRXLBProblem Description:CQR and XLB are best friends. One night, they are staring each other and feel boring, and XLB says let's play game! They place n piles of stones and take turns remove arbitrary amount(at least one) of stones in at least one pile at most x piles they chose. The one who can not remove any stone lose out. CQR is a girl so she always move first. Duoxida wants to know who will win if they are both smart enough. InputThe first line contains a integer T(no more than 100) indicating the number of test cases. In each test case, each test case includes two lines. the first line contains two integers n and x \\((1\\le n\\le 100, 1\\le x\\le 9)\\). The second line contains n positive integers indicates the amount of stones in each pile. All inputs are no more than \\(10^9\\). OutputFor each test case, puts the name of winner if they both acts perfect. Sample Input2 Sample OutputXLB SourceXTU OnlineJudge |
题意:有N堆石子,两个人在玩游戏。游戏规则是可以取不超过x堆中任意石子数,至少取一个,不能取者败,问先手还是后手赢。
那我们就需要设计出该石子堆的平衡状态和非平衡状态。
显然发现,这道题类似于NIM+BASH博弈。
别问为什么,赛场上我肯定推不出来的,只能靠猜想+证明。
猜想:将每个石子堆$n_{k}$ 变为二进制数,对所有的$n_{k}$,把各位分别加起来,并%(x+1),然后把各位求和sum。若sum==0则后手赢,否则先手赢。
公平组合博弈的平衡和非平衡态满足的条件:
• 1、平衡态时,不可能转移到另外的平衡态。
• 2、非平衡态时,一定可以转移到平衡态的状态。
• 3、最终的状态是平衡态。且有限步数内会结束。
显然上面的sum==0对应平衡态,sum!=0对应非平衡态,读者可以自己证明下。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #define clr(x) memset(x,0,sizeof(x)) 5 using namespace std; 6 int a[100]; 7 int max(int a,int b) 8 { 9 return a>b?a:b; 10 } 11 int main() 12 { 13 int n,m,k,t,l,maxt,sum; 14 int T; 15 scanf("%d",&T); 16 while(T--) 17 { 18 scanf("%d%d",&n,&m); 19 clr(a); 20 maxt=0; 21 for(int i=1;i<=n;i++) 22 { 23 scanf("%d",&l); 24 t=0; 25 while(l) 26 { 27 t++; 28 a[t]=(a[t]+(l%2))%(m+1); 29 l/=2; 30 } 31 32 maxt=max(maxt,t); 33 } 34 sum=0; 35 for(int i=1;i<=maxt;i++) 36 { 37 sum+=a[i]; 38 } 39 if(sum) 40 printf("CQR\n"); 41 else 42 printf("XLB\n"); 43 } 44 return 0; 45 }