【题目】

Description

The funny stone game is coming. There are n piles of stones, numbered with 0, 1, 2, ..., n − 1. Two
persons pick stones in turn. In every turn, each person selects three piles of stones numbered i, j, k
(i < j, j ≤ k and at least one stone left in pile i). Then, the person gets one stone out of pile i, and
put one stone into pile j and pile k respectively. (Note: if j = k, it will be the same as putting two
stones into pile j). One will fail if he can’t pick stones according to the rule.
David is the player who first picks stones and he hopes to win the game. Can you write a program
to help him?
The number of piles, n, does not exceed 23. The number of stones in each pile does not exceed 1000.
Suppose the opponent player is very smart and he will follow the optimized strategy to pick stones.

Input
Input contains several cases. Each case has two lines. The first line contains a positive integer n
(1 ≤ n ≤ 23) indicating the number of piles of stones. The second line contains n non-negative integers
separated by blanks, S0, . . . , Sn−1 (0 ≤ Si ≤ 1000), indicating the number of stones in pile 0 to pile
n − 1 respectively.
The last case is followed by a line containing a zero.
Output
For each case, output a line in the format ‘Game t: i j k’. t is the case number. i, j and k indicates
which three piles David shall select at the first step if he wants to win. If there are multiple groups of
i, j and k, output the group with the minimized lexicographic order. If there are no strategies to win
the game, i, j and k are equal to ‘-1’.

Sample Input
4
1 0 1 100
3
1 0 5
2
2 1
0
Sample Output
Game 1: 0 2 3
Game 2: 0 1 1
Game 3: -1 -1 -1

【题目翻译】

  David 玩一个石子游戏。游戏中,有n堆石子,被编号为0..n-1。两名玩家轮流取石子。每一轮游戏,每名玩家选取3堆石子i,j,k(i<j,j<=k,且至少有一枚石子在第i堆石子中),从i中取出一枚石子,并向j,k中各放入一枚石子(如果j=k则向k中放入2颗石子)。最先不能取石子的人输。

请编程帮助David。

石子堆的个数不会超过23,每一堆石子不超过1000个。

【分析】

  首先,假设第i堆有xi个石子,那么可以先把xi%2。

  因为在同一堆中的两颗石子是一模一样的。对方对这颗石子做什么,你就可以对另外一颗石子做同样的事,相当于这两颗一样的石子不存在。

  因为每颗石子可以变成两颗放到后面去,也就是说它的转移状态和它的编号有关。

  可以将每一颗石子看作是一堆石子,如果它是第p堆中的石子,把么它所代表的这堆石子的个数为n-1-p。

  因为石子堆是互不干扰的,因此这个游戏可以看作由若干个只有一堆石子的游戏组成。(把其单独考虑开来)

  求它能到达的子状态的尼姆和更新自己的sg值即可。跟扫楼梯一题差不多,即使这堆石子的个数为偶数个,他可能还是有用的,即可以拆分也把状态改变为平衡状态的,要把这个也考虑上。(好像说得不是很清楚,具体看代码吧~~)

代码如下:(看错数据范围了,懒得改了,就酱吧~)

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 #include<queue>
 7 using namespace std;
 8 #define Maxn 1010
 9
10 int n;
11 int a[2*Maxn],b[2*Maxn],sg[2*Maxn];
12 bool vis[2*Maxn];
13
14 void get_sg(int x)
15 {
16     memset(vis,0,sizeof(vis));
17     for(int i=1;i<x;i++)
18      for(int j=i;j<x;j++)
19      {
20          vis[sg[i]^sg[j]]=1;
21      }
22     for(int i=0;i<=2000;i++)
23         if(vis[i]==0) {sg[x]=i;break;}
24 }
25
26 bool output(int x,int now)
27 {
28     for(int i=x-1;i>=1;i--)
29      for(int j=i;j>=1;j--)
30       if((sg[i]^sg[j])==now)
31       {
32           printf("%d %d %d\n",n-x,n-i,n-j);
33           return 1;
34       }
35     return 0;
36 }
37
38 int main()
39 {
40     int kase=0;
41     for(int i=1;i<=1000;i++) get_sg(i);
42     while(1)
43     {
44         scanf("%d",&n);
45         if(n==0) break;
46         int ans=0;
47         for(int i=1;i<=n;i++) scanf("%d",&a[i]);
48         for(int i=1;i<=n;i++) b[i]=a[n-i+1];
49         for(int i=1;i<=n;i++)
50         {
51             if(b[i]%2==1) ans^=sg[i];
52         }
53         printf("Game %d: ",++kase);
54         if(ans==0) {printf("-1 -1 -1\n");continue;}
55         int mx=0;
56         for(int i=0;(1<<i)<=ans;i++)
57             if((1<<i)&ans) mx=(1<<i);
58         for(int i=n;i>=1;i--)
59             if(b[i]!=0) {if(output(i,ans^sg[i])) break;}
60     }
61     return 0;
62 }

[UVA1378]

2016-04-17 17:12:38

转载于:https://www.cnblogs.com/Konjakmoyu/p/5401461.html

【UVA1378】A Funny Stone Game (博弈-求SG值-输出方案)相关推荐

  1. 博弈论(Bash博弈、Nim博弈、SG函数、组合博弈)

    组合博弈入门 一.博弈论三条性质: 终结点为P点 P点只能到N点 N点至少有一种途径到P点 N:必胜态 P:必败态    1.引导题 1846 Brave Game 题目大意: n个石子两人轮流取1~ ...

  2. 组合博弈游戏 - SG函数和SG定理

    转载来自:http://blog.csdn.net/luomingjun12315/article/details/45555495 在介绍SG函数和SG定理之前我们先介绍介绍必胜点与必败点吧. 必胜 ...

  3. 【博弈论】博弈论入门笔记(四类基础博弈结论+SG函数)

    1.巴什博奕(Bash Game): 只有一堆n个物品,两个人轮流轮流从中取物,每次最少取一个,最多取m个,最后取光的人获胜.(谁拿了最后一个谁赢) 结论: 1.if(n%(m+1) != 0) ,则 ...

  4. 【博弈】SG函数模板 nyoj913取石子(十)

    SG函数模板 源于http://www.cnblogs.com/frog112111/p/3199780.html 首先定义mex(minimal excludant)运算,这是施加于一个集合的运算, ...

  5. 蓝桥杯-递归求二项式系数值(java)

    算法训练 6-1 递归求二项式系数值 时间限制:10.0s 内存限制:256.0MB问题描述样例输入一个满足题目要求的输入范例.3 10样例输出与上面的样例输入对应的输出.数据规模和约定输入数据中每一 ...

  6. asin c语言中 返回值范围_asin()_C语言asin()详解:反正弦函数,求反正弦值

    double asin(double x); asin() 函数的功能是求反正弦值. 反正弦函数 asin() 和正弦函数 sin() 的功能正好相反:sin() 是已知一个角的弧度值 x,求该角的正 ...

  7. 1470: 区间求最值(RMQ问题,ST算法模板)

    1470: 区间求最值 Time Limit: 1 Sec Memory Limit: 128 MB [Submit][Status][Web Board] Description 给定一个长度为N ...

  8. 函数最值题目及答案_呆哥数学每日一题 ——多元函数求最值

    如果想要获取往期每日一题电子版,可以加我微信:daigemath166,备注:知乎 每日一题 呆哥解析: 这是一个多元函数求最值的原创题 看到这个形式这么复杂,我们该怎么处理呢? 我个人想到一个方法是 ...

  9. 2021牛客第一场H.Hash Function—FFT求差值的卷

    https://ac.nowcoder.com/acm/contest/11166/H 官方题解. 比赛时,我们都是用暴力写的,数据太弱了,今天突然想起来,用fft写了一下. 主要使用fft求差值的卷 ...

最新文章

  1. golang学习笔记————字符串
  2. 8080端口被其他程序占用,Failed to start connector [Connector[HTTP/1.1-8080]],查看占用程序并关闭
  3. LightOJ 1370 - Bi-shoe and Phi-shoe
  4. SAP Spartacus organization unit list的实现Component
  5. 梯度下降法、随机梯度下降法、批量梯度下降法及牛顿法、拟牛顿法、共轭梯度法
  6. matlab算hht,关于MATLAB中HHT谱图的问题【百度知道悬赏100积分】
  7. 你知道Java的四种引用类型吗
  8. azure云数据库_如何将MySQL表迁移到Microsoft Azure SQL数据库
  9. e.target+addEventListener事件委托
  10. python计算工资编程-Python实现扣除个人税后的工资计算器示例
  11. POJ 1472 Instant Complexity
  12. 回顾 2018: 革新的一年
  13. cv2.error: OpenCV(4.5.3) C:\Users\runneradmin\AppData\Local\Temp\pip-req-build-q3d_8t8e\opencv\modul
  14. ★自助饮料售卖机,C语言 编辑题
  15. 历史类:罗马帝国兴亡史
  16. Guideline 2.3.3 -- We noticed that your screenshots do not sufficiently reflect your app in use
  17. 投资学翻译2 Digesting Anomalies An Investment Approach
  18. 三菱FX5U系列PLC控制10轴设备成套资料打包三菱FX5U控制10轴伺服的设备成套电气图纸
  19. Mapped Statements collection does not contain value for 解决方法之一
  20. nvcc fatal : No input files specified; use option --help for more information

热门文章

  1. Ubuntu 14 配置Android Studio的快捷启动方式
  2. kernel 3.10内核源码分析--中断--中断和异常返回流程
  3. 如何成立一家私募基金公司
  4. 学java的正确方法_学习Java编程 这10个技巧不容错过--中享思途
  5. 二叉树的基本特性和二叉树的几种基本操作的机制_关于二叉树,你该了解这些!...
  6. mysql查询时间类型c语言处理_资讯类app用户热度及资讯类型分析-Mysql进行数据预处理...
  7. 关联规则挖掘算法_数据挖掘 | 关联规则分析
  8. 论文参考文献的组织(latex)
  9. hust1344(阶层问题+暴力)
  10. android用qq浏览器打开微信网页版,QQ浏览器怎么打开微信小程序?