xtuoj 1235 CQRXLB(博弈论)

CQRXLB

Accepted : 19   Submit : 40
Time Limit : 1000 MS   Memory Limit : 65536 KB

CQRXLB

Problem 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.

Input

The 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\).

Output

For each test case, puts the name of winner if they both acts perfect.

Sample Input

2
3 1
1 3 2
2 2
1000 1000

Sample Output

XLB
CQR


Source

XTU OnlineJudge 

题意:有N堆石子,两个人在玩游戏。游戏规则是可以取不超过x堆中任意石子数,至少取一个,不能取者败,问先手还是后手赢。

那我们就需要设计出该石子堆的平衡状态和非平衡状态。

显然发现,这道题类似于NIM+BASH博弈。

别问为什么,赛场上我肯定推不出来的,只能靠猜想+证明。

猜想:将每个石子堆$n_{k}$ 变为二进制数,对所有的$n_{k}$,把各位分别加起来,并%(x+1),然后把各位求和sum。若sum==0则后手赢,否则先手赢。

公平组合博弈的平衡和非平衡态满足的条件:
• 1、平衡态时,不可能转移到另外的平衡态。
• 2、非平衡态时,一定可以转移到平衡态的状态。
• 3、最终的状态是平衡态。且有限步数内会结束。

显然上面的sum==0对应平衡态,sum!=0对应非平衡态,读者可以自己证明下。

 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
");
41         else
42             printf("XLB
");
43     }
44     return 0;
45 }
博弈论
原文地址:https://www.cnblogs.com/wujiechao/p/6859136.html