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 ijk (i < jjk 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 - 1respectively.

The last case is followed by a line containing a zero.

Output

For each case, output a line in the format `` Game tijk". t is the case number. ij and k indicates which three piles David shall select at the first step if he wants to win. If there are multiple groups of ij and k, output the group with the minimized lexicographic order. If there are no strategies to win the game, ijand k are equal to -1.
 
题目大意:有n堆石头,第i堆石头有Si个石头,每次可以从第i堆石头拿掉一个石头,然后在第j、k(i<j、k)上各放一个石头。两人轮流操作,不能操作的人算输,问先手第一步的必胜策略是什么,输出最小字典序的答案。
思路:利用SG函数来做。可以把每个石头看作是独立的游戏,那么对于某个在第i位的石头,它的后续状态是所有的在第j、k位的两个石头,这两个石头也是独立的游戏,那么sg[i] = mex{sg[j] ^ sg[k]},对于每个位置的sg[i]可以O(n^3)预先计算出来。
然后所有的石头的SG值异或若等于0则输出-1-1-1(对于每一个Si,若Si为奇数,则异或一次,若Si为偶数,则不异或,因为一个数异或偶数次,肯定是0,复杂度为O(n)),否则O(n^3)暴力枚举方案,若sg[i]^sg[j]^sg[k]^ans==0,则i、j、k是必胜方案,其中ans是所有石头SG值异或的结果。
就是一步操作i、j、k,sg[i]会变成sg[j]^sg[k],那么若原来的SG值为ans,又sg[i]^sg[j]^sg[k]^ans==0,那么新状态的SG值就为0(可以参考NIM博弈的证明)。
 
代码(3MS):
 #include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
using namespace std; const int MAXN = ; int sg[MAXN + ];
bool mex[MAXN * MAXN];
int n, s[MAXN]; void build_sg() {
for(int i = MAXN - ; i >= ; --i) {
memset(mex, , sizeof(mex));
for(int j = i + ; j < MAXN; ++j) {
for(int k = j; k < MAXN; ++k) mex[sg[j] ^ sg[k]] = true;
}
for(int j = ; ; ++j)
if(!mex[j]) {sg[i] = j; break;}
}
} void solve() {
int ans = , *sg = ::sg + MAXN - n;
for(int i = ; i < n; ++i) ans ^= sg[i] * (s[i] & );
if(ans == ) {
printf(" -1 -1 -1\n");
return ;
}
for(int i = ; i < n; ++i) {
if(s[i] == ) continue;
for(int j = i + ; j < n; ++j) {
for(int k = j; k < n; ++k) {
if((sg[i] ^ sg[j] ^ sg[k] ^ ans) == ) {
printf(" %d %d %d\n", i, j, k);
return ;
}
}
}
}
} int main() {
build_sg();
int cnt = ;
while(scanf("%d", &n) != EOF && n) {
for(int i = ; i < n; ++i) scanf("%d", &s[i]);
printf("Game %d:", ++cnt);
solve();
}
}

UVALive 3668 A Funny Stone Game(博弈)的更多相关文章

  1. UVALive 3668 A Funny Stone Game

    题目链接:UVALive - 3668 题目大意为给定n堆石子,每次的操作是选择三个数i<j<=k,从i中拿一枚石子,在j和k中分别放入一枚石子.不能操作者输.求先手是否能赢,若可以,则输 ...

  2. Light OJ 1296 - Again Stone Game (博弈sg函数递推)

    F - Again Stone Game Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu ...

  3. HDU 4764 Stone(博弈)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4764 题目大意:Tang和Jiang玩石子游戏,给定n个石子,每次取[1,k]个石子,最先取完的人失败 ...

  4. poj1740 A New Stone Game[博弈]

    有若干堆石子,每一次需要从一堆石子中拿走一些,然后如果愿意的话,再从这堆石子中拿一些(揣度题意应该是不能拿出全部)分给其它任意不为空的堆.不能操作的人为负. 一直不会博弈啊..感觉完全就是个智商题,虽 ...

  5. HDU 4387 Stone Game (博弈)

    题目:传送门. 题意:长度为N的格子,Alice和Bob各占了最左边以及最右边K个格子,每回合每人可以选择一个棋子往对面最近的一个空格移动.最先不能移动的人获得胜利. 题解: k=1时 很容易看出,n ...

  6. UVALive 6913 I Want That Cake 博弈dp

    I Want That Cake 题目连接: https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemi ...

  7. UVALive 6913 I Want That Cake 博弈+dp

    题目链接: http://acm.hust.edu.cn/vjudge/problem/96343 I Want That Cake Time Limit: 3000MS 64bit IO Forma ...

  8. Contest 7.23(不知道算什么)

    Problem A   URAL 1181 Cutting a Painted Polygon 题目大意就是说有一个N边形,让你做N-3条边,让他们的每个三角形的三个顶点颜色都不相同. 这里有一个引理 ...

  9. 2018.12.1 Test

    目录 2018.12.1 Test A 串string(思路) B 变量variable(最小割ISAP) C 取石子stone(思路 博弈) 考试代码 B C 2018.12.1 Test 题目为2 ...

随机推荐

  1. HTML如何禁止input输入

    第一种方法: 在input元素上加readonly="readonly"属性 <input type="text" readonly="read ...

  2. youku客户端

    文件结构 config import os IP_PORT = ('127.0.0.1',8080) BASE_DIR = os.path.dirname(os.path.dirname(__file ...

  3. Linux基础(05)、Linux进阶命令

    目录 一.进阶命令 二.系统命令 三.压缩和归档 3.1.归档 3.2.压缩 3.3.归档并压缩 归档.接档:tar -cf.tar -tvf 压缩.解压:gzip.gunzip 归档并压缩:tar ...

  4. vue分页组件重置到首页问题

    分页组件,可以借用这个老哥的@暴脾气大大https://www.cnblogs.com/sebastian-tyd/p/7853188.html#4163272 但是有一个问题就是下面评论中@ Mrz ...

  5. 5、GDB调试工具的使用

    GDB是GNU发布的一款功能强大的程序调试工具.GDB主要完成下面三个方面的功能: 1.启动被调试程序. 2.让被调试的程序在指定的位置停住. 3.当程序被停住时,可以检查程序状态(如变量值). #i ...

  6. 决策树&随机森林

    参考链接: https://www.bilibili.com/video/av26086646/?p=8 <统计学习方法> 一.决策树算法: 1.训练阶段(决策树学习),也就是说:怎么样构 ...

  7. pygame---制作一只会转弯的小乌龟

    Pygame Pygame是跨平台Python模块,专为电子游戏设计,包含图像.声音.建立在SDL基础上,允许实时电子游戏研发而无需被低级语言(如机器语言和汇编语言)束缚. 包含图像.声音. 建立在S ...

  8. python中自定义超时异常的几种方法

    最近在项目中调用第三方接口时候,经常会出现请求超时的情况,或者参数的问题导致调用异代码异常.针对超时异常,查询了python 相关文档,没有并发现完善的包来根据用户自定义的时间来抛出超时异常的模块.所 ...

  9. APP如何发布到Google play 商店

    APP如何发布到Google play 商店?以及有哪些需要注意的点 2015-05-13 10:07 19773人阅读 评论(1) 收藏 举报  分类: iPhone游戏开发(330)  链接:ht ...

  10. 成都Uber优步司机奖励政策(1月16日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...