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)。
如果轮到某人而他无法按规则取豆子,那么他将输掉比赛。胜利者可以拿走所有的巧克力豆!
两人最后决定由聪聪先取豆子,为了能够得到最终的巧克力豆,聪聪自然希望赢得比赛。
他思考了一下,发现在有的情况下,先拿的人一定有办法取胜,但是他不知道对于其他情况是否有必胜策略,更不知道第一步该如何取。
他决定偷偷请教聪明的你,希望你能告诉他,在给定每个瓶子中的最初豆子数后是否能让自己得到所有巧克力豆,他还希望你告诉他第一步该如何取,并且为了必胜,第一步有多少种取法?
假定 1 < n < = 21,p[i] < = 10000

Input

输入文件第一行是一个整数t表示测试数据的组数,
接下来为t组测试数据(t<=10)。
每组测试数据的第一行是瓶子的个数n,
接下来的一行有n个由空格隔开的非负整数,表示每个瓶子中的豆子数。

Output

对于每组测试数据,输出包括两行,
第一行为用一个空格两两隔开的三个整数,表示要想赢得游戏,
第一步应该选取的3个瓶子的编号i,j,k,
如果有多组符合要求的解,那么输出字典序最小的一组。
如果无论如何都无法赢得游戏,那么输出用一个空格两两隔开的三个-1。
第二行表示要想确保赢得比赛,第一步有多少种不同的取法。

Sample Input

2
4
1 0 1 5000
3
0 0 1

Sample Output

0 2 3
1
-1 -1 -1
0

Solution

首先可以发现,若一个位置豆子是偶数,且先手取了这个位置,显然后手可以通过进行和先手相同的操作来抵消这一步。

所以就可以把每个位置的豆子数$mod~2$,并将他们看成一个单独的游戏,同时记搜一下这个游戏的$SG$值。

虽然把每个豆子看成单独的游戏,但显然他们的$SG$值是可以共用的。

记忆化搜索每个豆子的$SG$值,当前是第$i$个位置的话显然有多种后继状态,每一种的$SG$值是$SG[j]~xor~SG[k]$。因为当前第$i$个位置的后继状态可以看做是$j$和$k$两个子局面的$SG$值异或得到总局面$SG$值。

输出方案就枚举三个位置$i,j,k$,如果全局异或值$ ~xor~ SG[i] ~xor~ SG[j] ~xor~ SG[k]=0$,那么说明先手取完这三个位置之后后手就必输了。

Code

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

BZOJ1188:[HNOI2007]分裂游戏(博弈论)的更多相关文章

  1. bzoj1188 [HNOI2007]分裂游戏 博弈论 sg函数的应用

    1188: [HNOI2007]分裂游戏 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 973  Solved: 599[Submit][Status ...

  2. [bzoj1188][HNOI2007]分裂游戏_博弈论

    分裂游戏 bzoj-1188 HNOI-2007 题目大意:题目链接. 注释:略. 想法: 我们发现如果一个瓶子内的小球个数是奇数才是有效的. 所以我们就可以将问题变成了一个瓶子里最多只有一个球球. ...

  3. [BZOJ1188][HNOI2007]分裂游戏(博弈论)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1188 分析: 设SG[i]表示一个石子在位置i上的SG值 这个很容易暴力求,因为i的后 ...

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

    因为第i个瓶子里的所有豆子都是等价的,设sg(i)表示第i个瓶子的sg值,可以转移到sg(j)^sg(k)(i<j<n,j<=k<n)的状态. 只需要考虑豆子数是奇数的瓶子啦, ...

  5. BZOJ1188 [HNOI2007]分裂游戏(SG函数)

    传送门 拿到这道题就知道是典型的博弈论,但是却不知道怎么设计它的SG函数.看了解析一类组合游戏这篇论文之后才知道这道题应该怎么做. 这道题需要奇特的模型转换.即把每一个石子当做一堆石子,且原来在第i堆 ...

  6. bzoj1188: [HNOI2007]分裂游戏

    Description 聪聪和睿睿最近迷上了一款叫做分裂的游戏. 该游戏的规则试: 共有 n 个瓶子, 标号为 0,1,2.....n-1, 第 i 个瓶子中装有 p[i]颗巧克力豆,两个人轮流取豆子 ...

  7. [HNOI2007]分裂游戏 博弈论

    题面 题面 题解 这题的思路比较特别,观察到我们的每次操作实质上是对于一颗豆子的操作,而不是对一瓶豆子的操作,因此我们要把每颗豆子当做一个独立的游戏,而它所在的瓶子代表了它的SG值. 瓶子数量很少,因 ...

  8. 【BZOJ1188】分裂游戏(博弈论)

    [BZOJ1188]分裂游戏(博弈论) 题面 BZOJ 洛谷 题解 这道题目比较神仙. 首先观察结束状态,即\(P\)状态,此时必定是所有的豆子都在最后一个瓶子中. 发现每次的转移一定是拿出一棵豆子, ...

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

    1188: [HNOI2007]分裂游戏 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 733  Solved: 451[Submit][Status ...

随机推荐

  1. 自定义提醒视图Alert-动态绘制

    1. .h文件 #import <UIKit/UIKit.h> #define Wi [[UIScreen mainScreen]bounds].size.width #define He ...

  2. WPF绑定之索引器值变化通知

    背景 在某些应用中,需要在界面上绑定到索引器,并在值发生变化时实时更新. 解决方案 只要将包含索引器的类实现INotifyPropertyChanged接口,并在索引值更改时引发PropertyCha ...

  3. Windows应用程序对键盘与鼠标的响应

      编写程序: 设计一个窗口, 当单击鼠标左键时, 窗口中显示"LEFT BUTTON"; 当单击鼠标右键时, 窗口中显示"RIGHT BUTTON"; 当单击 ...

  4. Messenger与AIDL的异同

    Messenger与AIDL的异同 最近做项目需要使用进程间通信,大家知道应用层的进程间通信无非Broadcast,Activity,Service,Content Provider四大组件.Broa ...

  5. zookeeper 典型应用

    一.发布/订阅 配置文件的集中管理. 问题:当分布式系统变多后,每个系统保存相应的配置文件,会造成同个文件有多份,修改起来非常麻烦. 解决方法:使用zk的发布/订阅功能,配合Watcher机制,在应用 ...

  6. 视区相关单位vw, vh..简介以及可实际应用场景——张鑫旭

    一.N多的唠哩唠叨 CSS3中一些新的单位早在去年春暖花开的时候就介绍了,参见:CSS长度值及时间.频率.角度单位.显然,其中就提到了本文要感叹的单位vw, vh,见下图: 不过“我看见你”和“我触碰 ...

  7. Web 开发者学习路线图

      2017 Web 开发者学习路线图(头图源自谷歌) 本文是源自 Github 上 Kamran Ahmed 建立的一个仓库.在文中,作者为他的老教授分享了一组成为前端与后端开发者以及 Devops ...

  8. gotop(返回顶部)

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. js面向对象设计之function类

    本文仅探讨如何合理的使用 function 在 javascript中实现一个面向对象设计的类.总所周知,javascript 并不能实现一个真正意义上的类,比如 protect 比如 函数重载.下面 ...

  10. Python入门与基本概念

    简介:本学习笔记基于ubuntu,Ubuntu已经内置了python2.7,python2.7既包含老版本的属性,有含有新版本的一些特性,用于对3.x版本的过渡,可以拿来入门学习,入门之后可以再学习p ...