BZOJ3759: Hungergame

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3759

题解:只想到了两种情况必胜,没有推广T_T

先说一下我想到了两种情况:

1)异或和为0  我们一次打开所有的就成了普通的nim游戏。

2)存在n-1的元素的自己异或和为0,那我们把这n-1个箱子打开,然后另一个人如果打开另一个,就成了nim,否则我们把这n-1堆取完,然后它打开我们取完。如果它中途打开了,我们下一步就把最后这堆取完,最终还是我们赢。

正解是必胜的充要条件是存在异或和为0的非空子集。

如何证明?我还是搬运题解吧T_T

http://blog.csdn.net/popoqqq/article/details/41519895

Orz POPOQQQ

代码:

 1 #include<cstdio>
 2
 3 #include<cstdlib>
 4
 5 #include<cmath>
 6
 7 #include<cstring>
 8
 9 #include<algorithm>
10
11 #include<iostream>
12
13 #include<vector>
14
15 #include<map>
16
17 #include<set>
18
19 #include<queue>
20
21 #include<string>
22
23 #define inf 1000000000
24
25 #define maxn 200000+5
26
27 #define maxm 200000+5
28
29 #define eps 1e-10
30
31 #define ll long long
32
33 #define pa pair<int,int>
34
35 #define for0(i,n) for(int i=0;i<=(n);i++)
36
37 #define for1(i,n) for(int i=1;i<=(n);i++)
38
39 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
40
41 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
42
43 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
44
45 #define for5(n,m) for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)
46
47 #define mod 1000000007
48
49 using namespace std;
50
51 inline int read()
52
53 {
54
55     int x=0,f=1;char ch=getchar();
56
57     while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
58
59     while(ch>=‘0‘&&ch<=‘9‘){x=10*x+ch-‘0‘;ch=getchar();}
60
61     return x*f;
62
63 }
64 int a[100],b[100],n;
65 inline bool gauss()
66 {
67     memset(b,0,sizeof(b));
68     for1(i,n)
69     {
70      for3(j,30,0)
71       if(a[i]>>j&1)
72       {
73           if(!b[j]){b[j]=a[i];break;}
74           else a[i]^=b[j];
75       }
76      if(!a[i])return 1;
77     }
78     return 0;
79 }
80
81 int main()
82
83 {
84
85     freopen("input.txt","r",stdin);
86
87     freopen("output.txt","w",stdout);
88
89     int T=read();
90     while(T--)
91     {
92        n=read();
93        for1(i,n)a[i]=read();
94        puts(gauss()?"Yes":"No");
95     }
96
97     return 0;
98
99 }  

时间: 2024-11-03 13:34:46

BZOJ3759: Hungergame的相关文章

BZOJ3759: Hungergame 博弈论+线性基

学了新的忘了旧的,还活着干什么 题意:一些盒子,每步可选择打开盒子和取出已打开盒子的任意多石子,问先手是否必胜 搬运po姐的题解: 先手必胜的状态为:给出的数字集合存在一个异或和为零的非空子集,则先手必胜 证明: 首先我们有状态A:当前的所有打开的箱子中的石子数异或和为零,且所有关闭的箱子中的石子数的集合中不存在一个异或和为零的非空子集 易证A状态时先手必败 先手有两种操作: 1.从一个打开的箱子中拿走一些石子 那么根据Nim的结论 后手可以同样拿走一些石子使状态恢复为A状态 2.打开一些箱子

BZOJ 3759 Hungergame 博弈论+高斯消元

题目大意:给定一些箱子,每个箱子里有一些石子,两个人轮流操作,每个人可以进行以下操作之一: 1.打开任意多的箱子 2.从一个打开的箱子中拿走任意多的石子 不能操作者判负,求先手是否必胜 先手必胜的状态为:给出的数字集合存在一个异或和为零的非空子集,则先手必胜 证明: 首先我们有状态A:当前的所有打开的箱子中的石子数异或和为零,且所有关闭的箱子中的石子数的集合中不存在一个异或和为零的非空子集 易证A状态时先手必败 先手有两种操作: 1.从一个打开的箱子中拿走一些石子 那么根据Nim的结论 后手可以

【BZOJ】【3759】Hungergame饥饿游戏

博弈论/高斯消元 如果没有打开箱子这个操作,那么就是一个很裸的Nim游戏…… 但是有了打开箱子这个操作,就变得蛋疼了T_T 首先我们可以想到一种直接的做法:打开所有箱子,当然如果此时所有a[i]的xor和==0则胜…… 但明显这样连样例也过不了╮(╯▽╰)╭ 那么我们可以想一下,对于一组全部没打开的箱子,我们进行一次操作后,会分成两组:打开的和没打开的(废话!) so sad……写不下去了…… 算了 Orz一下PoPoQQQ,搬运下题解: 先手必胜的状态为:给出的数字集合存在一个异或和为零的非空

[bzoj359]Hungergame

bz不支持提交了,我觉得我写的应该没啥问题. 题面https://www.lydsy.com/JudgeOnline/problem.php?id=3759 我们知道Nim游戏如果所有石子数异或和等于0,那么后手必胜.所以作为先手,策略是这样的: 如果存在异或和为0的子集,那么一定存在一个最大的异或和为0的子集,称它为A.它的补集B不存在异或和为0的子集.(因为我们可以把为0的所有小子集合并)于是我们把A的盖子都打开. 接下来如果后手跟我们取A里的石子,像普通的Nim一样,我们总是取和他异或得0