题目链接:https://vjudge.net/problem/UVA-1378

题意:

两个人玩游戏,有n堆石子,两人轮流操作:于第i堆石子中取走一块石子,然后再往第j、k堆中各添加一块石子。其中 i<j, j<=k。最后一次操作的为赢家,问先手能否必胜,如果能,请输出第一步操作。

题解:

1.把每个石子都看成是一个子游戏,所以在第i堆的其中一个石子,它的下一步为第j堆和第k堆;即这个子游戏又可以分解为两个子游戏。

2.由于在同一堆里的石子状态完全相同,所以当这堆石子的个数为偶数时,他们的SG值异或和为0;当个数为奇数时,他们的SG值异或和即为单独一个石子的SG值。

3.那么怎么求在第i堆里一个石子的SG值呢?一般情况下子游戏的下标是较小的,而处于第i堆的石子游戏又可以分解为处于第j、k石子的子游戏,然后i是小于j、k的,所以我们就把下标翻过来,这样就满足的SG的求值过程。初始状态为SG[0] = 0,即位于第0堆时,无法操作,即无后续状态,所以 SG[0] = mex{} = 0。

4.至于输出第一步,枚举ijk,得到一个必败状态即可。为何是必败状态?因为先手是处于必胜状态,当先手操作了一轮之后,轮到后手,而后手就处于必败状态。

代码如下:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
using namespace std;
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int MOD = 1e9+;
const int MAXN = +; int a[MAXN], SG[MAXN], vis[]; void getSG()
{
SG[] = ;
for(int i = ; i<MAXN; i++)
{
memset(vis, , sizeof(vis));
for(int j = ; j<i; j++)
for(int k = ; k<=j; k++)
vis[SG[j]^SG[k]] = ; //下一个状态,由两个子游戏组成,故异或。 for(int j = ;;j++) if(!vis[j]) {
SG[i] = j;
break;
}
}
} int main()
{
getSG();
int n, kase = ;
loop:
while(scanf("%d",&n) && n)
{
int val = ;
for(int i = ; i<n; i++)
{
scanf("%d", &a[i]);
if(a[i]%) val ^= SG[n--i]; //当个数为奇数时,才有效
} printf("Game %d: ", ++kase);
for(int i = ; i<n-; i++) //枚举、模拟第一步操作
{
if(a[i]==) continue; //如果这堆没有石子,那就不能取了。
for(int j = i+; j<n; j++)
for(int k = j; k<n; k++) //取走i堆一块石子,往j、k堆中各加一个石子,即撤销i堆中一个子游戏
if((val^SG[n-i-]^SG[n--j]^SG[n--k])==){ //j、k堆中增加一个游戏。异或的作用是:有则去之无则添之。
printf("%d %d %d\n", i, j, k);
goto loop;
}
}
printf("-1 -1 -1\n");
}
return ;
}

UVA1378 A Funny Stone Game —— SG博弈的更多相关文章

  1. uva 1378 - A Funny Stone Game sg博弈

    题意:David 玩一个石子游戏. 游戏中,有n堆石子,被编号为0..n-1.两名玩家轮流取石子. 每一轮游戏.每名玩家选取3堆石子i,j,k(i<j,j<=k,且至少有一枚石子在第i堆石 ...

  2. UVA12293 Box Game —— SG博弈

    题目链接:https://vjudge.net/problem/UVA-12293 题意: 两人玩游戏,有两个盒子,开始时第一个盒子装了n个球, 第二个盒子装了一个球.每次操作都将刷量少的盒子的球倒掉 ...

  3. UVA1482 Playing With Stones —— SG博弈

    题目链接:https://vjudge.net/problem/UVA-1482 题意: 有n堆石子, 每堆石子有ai(ai<=1e18).两个人轮流取石子,要求每次只能从一堆石子中抽取不多于一 ...

  4. HDU 1848(sg博弈) Fibonacci again and again

    Fibonacci again and again Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Jav ...

  5. 【UVA1378】A Funny Stone Game (博弈-求SG值-输出方案)

    [题目] Description The funny stone game is coming. There are n piles of stones, numbered with 0, 1, 2, ...

  6. uva 1378 A Funny Stone Game (博弈-SG)

    题目链接:http://vjudge.net/problem/viewProblem.action?id=41555 把第i堆的每个石子看出一堆个数为n-i的石子,转换为组合游戏 #include & ...

  7. UVALive 3668 A Funny Stone Game(博弈)

    Description The funny stone game is coming. There are n piles of stones, numbered with 0, 1, 2,...,  ...

  8. hdu 1851(A Simple Game)(sg博弈)

    A Simple Game Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/65535 K (Java/Others)Tot ...

  9. poj 1740 A New Stone Game(博弈)

    A New Stone Game Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 5338   Accepted: 2926 ...

随机推荐

  1. 配置tomcat启动参数-Dfile.encoding=UTF-8后,IDEA控制台乱码

    配置tomcat启动参数-Dfile.encoding=UTF-8后,IDEA控制台出现乱码 解决方法: 在idea的bin目录(如:D:\JetBrains\IntelliJ IDEA 2018.1 ...

  2. Java---详解方法传值问题

    过程解析: 1.首先执行int[] arr={3,5,6,1,7,9,0},遇到数组先执行等式右边的,{3,5,6,1,7,9,0}会在堆内存中开辟一块空间,分成7小块,下标分别从0~6,先进行系统初 ...

  3. Tavas and Malekas

    题面 题目描述 给你两个字符串a和b,告诉所有你b在a中一定匹配的位置,求有中不同的字符串a.a的长度为n,b的长度为m,一定匹配的位置有p个.若b在a中的一定匹配的位置为x,说明a[x-x+m-1] ...

  4. mysql事务四种隔离级别

    事务的基本要素:原子性,一致性,隔离性,持久性. 事务并发问题:脏读,不可重复读,幻读. mysql隔离级别:read-uncommitted,read-committed,repeatable-re ...

  5. js中多行字符串拼接

    前言 我们会经常遇到这样的场景,需要拼接多行字符串,在字符串中动态插入一些数据以达到业务的需求.但是js中并没有标准的多行编辑的函数,于是聪明的程序员们便脑洞大开,书写出许多有趣的方法. 1 2 3 ...

  6. DevExpress控件GridControl使用 z

    设置选中行的背景色.而不改变前景色. EnableAppearanceFocusedCell = False, EnableAppearanceFocusedRow = False private v ...

  7. [Algorithm] Write a Depth First Search Algorithm for Graphs in JavaScript

    Depth first search is a graph search algorithm that starts at one node and uses recursion to travel ...

  8. IntelliJ IDEA 10.5.1 引用外部Jar包

    具体步骤: File -> Project Structure (ctrl + shift + alt + s ) -> Module -> Dependencies -> A ...

  9. 百科知识 DCR文件如何打开

    使用IE可以打开,但是需要先安装Adobe Shockwave Player 天空软件下载地址:http://fpdownload.macromedia.com/get/shockwave/defau ...

  10. python--网络编程--socket

    网络通信标准---网络协议 互联网协议--osi七层协议 五层协议:应用层:应用层.表示层.会话层          传输层:传输层    网络层:网络层    数据链路层:数据链路层    物理层: ...