【BZOJ1299】巧克力棒(Nim游戏,SG函数)

题意:TBL和X用巧克力棒玩游戏。每次一人可以从盒子里取出若干条巧克力棒,或是将一根取出的巧克力棒吃掉正整数长度。

TBL先手两人轮流,无法操作的人输。

他们以最佳策略一共进行了10轮(每次一盒)。你能预测胜负吗?

如果TBL胜则输出”NO”,否则输出”YES”

n<=14,a[i]<=1e9

思路:一个结论:Nim游戏中一个xor和不为0(先手必胜)的状态一定可以通过1步转化为xor和为0(先手必败)的状态

所以先手第一步只需要取出一个xor和为0的最长子序列

若后手选择加入新巧克力棒,先手可以通过1步将已经加入的Nim游戏变为xor和为0的局面

若后手选择取已经加入的部分,先手依然可以通过1步将后手行动过的局面的xor和变为0

所以只需要判断初始局面下存不存在xor和为0的子序列

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<cmath>
 6 typedef long long ll;
 7 using namespace std;
 8 #define N   210000
 9 #define oo  10000000
10 #define MOD 1000000007
11 
12 int a[N],b[N],f[N];
13 
14 int lowbit(int x)
15 {
16     return x&(-x);
17 }
18 
19 int main()
20 { 
21     for(int v=1;v<=10;v++)
22     {
23         int n;
24         scanf("%d",&n);
25         for(int i=1;i<=n;i++) scanf("%d",&a[i]);
26         int x=1;
27         for(int i=1;i<=n;i++)
28         {
29             b[x]=i;
30             x<<=1;
31         }
32         f[0]=0;
33         for(int i=1;i<=(1<<n)-1;i++) f[i]=f[i^lowbit(i)]^a[b[lowbit(i)]];
34         int ans=0;
35         for(int i=1;i<=(1<<n)-1;i++)
36          if(!f[i]) ans=1;
37         if(ans) printf("NO\n");
38          else printf("YES\n");
39     }        
40     return 0;
41 }
42     

 

posted on 2018-11-13 20:02  myx12345  阅读(396)  评论(0编辑  收藏  举报

导航