BZOJ P1188 HNOI2007 分裂游戏——solution

题目描述:

(<--这个)

组合游戏,——把每个石头看做一个游戏,

Multi_game——消去i上的石子后,,k上的游戏又多了一个;

于是就套用multi_game的模型即可

求解SG函数时,发现一个游戏的后继是谁只与其位置有关,于是可以用一个SG值代替一堆游戏的SG值;

求解完所有SG值,后异或即可;

代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 using namespace std;
 4 int a[25],n,sg[25],g[10010];
 5 int SG(int );
 6 int main()
 7 {
 8     int i,j,k,T,ans,tot;
 9     scanf("%d",&T);
10     while(T--){
11         ans=0;tot=0;
12         memset(sg,-1,sizeof(sg));
13         scanf("%d",&n);
14         for(i=1;i<=n;i++)
15             scanf("%d",&a[i]);
16         for(i=1;i<=n;i++)
17             if(a[i]&1)
18                 ans^=SG(i);
19         if(ans==0)
20             printf("-1 -1 -1\n0\n");
21         else{
22             for(i=1;i<=n;i++)
23                 for(j=i+1;j<=n;j++)
24                     for(k=j;k<=n;k++)
25                         if((ans^SG(i)^SG(j)^SG(k))==0){
26                             if(!tot)printf("%d %d %d\n",i-1,j-1,k-1);
27                             tot++;
28                         }
29             if(!tot)printf("-1 -1 -1\n");
30             printf("%d\n",tot);
31         }
32     }
33     return 0;
34 }
35 int SG(int x){
36     int i,j;
37     if(sg[x]!=-1)return sg[x];
38     if(x==n)return sg[x]=0;
39     memset(g,0,sizeof(g));
40     for(i=x+1;i<=n;i++)
41         for(j=i;j<=n;j++)
42             g[SG(i)^SG(j)]=1;
43     for(i=0;;i++)
44         if(!g[i])return sg[x]=i;
45 }
时间: 2024-10-10 08:43:06

BZOJ P1188 HNOI2007 分裂游戏——solution的相关文章

bzoj 1188 [HNOI2007]分裂游戏(SG函数,博弈)

1188: [HNOI2007]分裂游戏 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 733  Solved: 451[Submit][Status][Discuss] Description 聪 聪和睿睿最近迷上了一款叫做分裂的游戏. 该游戏的规则试: 共有 n 个瓶子, 标号为 0,1,2.....n-1, 第 i 个瓶子中装有 p[i]颗巧克力豆,两个人轮流取豆子,每一轮每人选择 3 个瓶子.标号为 i,j,k, 并要保证 i < j ,

[BZOJ 1188] [HNOI2007] 分裂游戏 【博弈论|SG函数】

题目链接:BZOJ - 1188 题目分析 我们把每一颗石子看做一个单个的游戏,它的 SG 值取决于它的位置. 对于一颗在 i 位置的石子,根据游戏规则,它的后继状态就是枚举符合条件的 j, k.然后后继状态就是 j 与 k 这两个游戏的和. 游戏的和的 SG 值就是几个单一游戏的 SG 值的异或和. 那么还是根据 SG 函数的定义 , 即 SG(u) = mex(SG(v)) ,预处理求出每个位置的 SG 值.一个位置的 SG 值与它后面的位置有关,是取决于它是倒数第几个位置,那么我们预处理求

BZOJ 1188: [HNOI2007]分裂游戏(multi-nim)

Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1386  Solved: 840[Submit][Status][Discuss] Description 聪聪和睿睿最近迷上了一款叫做分裂的游戏.该游戏的规则试:共有n个瓶子,标号为0,1,2.....n-1,第i个瓶子中 装有p[i]颗巧克力豆,两个人轮流取豆子,每一轮每人选择3个瓶子.标号为i,j,k,并要保证i<j,j<=k且第i个瓶子 中至少要有1颗巧克力豆,随后这个人从第i个瓶子中拿走

bzoj 1188 : [HNOI2007]分裂游戏 sg函数

题目链接 给n个位置, 每个位置有一个小球. 现在两个人进行操作, 每次操作可以选择一个位置i, 拿走一个小球.然后在位置j, k(i<j<=k)处放置一个小球. 问你先进行什么操作会先手必胜以及方法数量. 感觉这题好神 如果一个位置有偶数个小球, 那么等价于这个位置没有小球. 因为第二个人可以进行和第一个人相同的操作. 所以初始值%2. 然后我们把每个位置看成一个状态, 如果i有一个小球, 等价于j, k 也有一个小球. 然后转移. 方法数量就n^3枚举就可以了. #include <

【BZOJ 1188】 [HNOI2007]分裂游戏

Description 聪聪和睿睿最近迷上了一款叫做分裂的游戏. 该游戏的规则试: 共有 n 个瓶子, 标号为 0,1,2.....n-1, 第 i 个瓶子中装有 p[i]颗巧克力豆,两个人轮流取豆子,每一轮每人选择 3 个瓶子.标号为 i,j,k, 并要保证 i < j , j < = k 且第 i 个瓶子中至少要有 1 颗巧克力豆,随后这个人从第 i 个瓶子中拿走一颗豆 子并在 j,k 中各放入一粒豆子(j 可能等于 k) .如果轮到某人而他无法按规则取豆子,那么他将输 掉比赛.胜利者可以

Bzoj1188 [HNOI2007]分裂游戏

Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1110  Solved: 679 Description 聪聪和睿睿最近迷上了一款叫做分裂的游戏. 该游戏的规则试: 共有 n 个瓶子, 标号为 0,1,2.....n-1, 第 i 个瓶子中装有 p[i]颗巧克力豆,两个人轮流取豆子,每一轮每人选择 3 个瓶子.标号为 i,j,k, 并要保证 i < j , j < = k 且第 i 个瓶子中至少要有 1 颗巧克力豆,随后这个人从第 i 个瓶子中

BZOJ P1059 [ZJOI2007]矩阵游戏——solution

1059: [ZJOI2007]矩阵游戏 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4604  Solved: 2211[Submit][Status][Discuss] Description 小Q是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏——矩阵游戏.矩阵游戏在一个N *N黑白方阵进行(如同国际象棋一般,只是颜色是随意的).每次可以对该矩阵进行两种操作:行交换操作:选择 矩阵的任意两行,交换这两行(即交换对应格子的颜

【博弈论】【SG函数】【枚举】bzoj1188 [HNOI2007]分裂游戏

因为第i个瓶子里的所有豆子都是等价的,设sg(i)表示第i个瓶子的sg值,可以转移到sg(j)^sg(k)(i<j<n,j<=k<n)的状态. 只需要考虑豆子数是奇数的瓶子啦,因为如果豆子数是偶数,重复异或是没有意义的. 对于方案数什么的……枚举就好了. #include<cstdio> #include<cstring> #include<set> using namespace std; int T,n,a[21],SG[21]; int s

bzoj 5329 [SDOI2018] 战略游戏

bzoj 5329 [SDOI2018] 战略游戏 Link Solution 很容易想到虚树 然后发现是一个图... 现学圆方树,套上去,做完了(模板题?) 就是直接上广义圆方树先把这玩意转换成一棵树,然后对当前询问建立虚树,断掉虚树里任何一个点都合法(包括不出现的点,指那些在某个点和其虚树上父亲之间的点),统计一下即可 Code // Copyright lzt #include<stdio.h> #include<cstring> #include<cstdlib>