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. 学习笔记(2)centos7 下安装mysql

    centos7安装mysql 本文通过yum方式安装mysql 1.添加mysql yum 仓库 去mysql开发者中心(http://dev.mysql.com/downloads/repo/yum ...

  2. Vue.js与 ASP.NET Core 服务端渲染功能整合

    http://mgyongyosi.com/2016/Vuejs-server-side-rendering-with-aspnet-core/ 原作者:Mihály Gyöngyösi 译者:oop ...

  3. hive 入门

    hive-site.xml 配置 <configuration> <property> <name>javax.jdo.option.ConnectionURL&l ...

  4. 基于Python的飞机大战游戏

    前几天决定学Python,上网找了教程看了两天,和C比起来面向对象的特性真的都很便捷,有了类开发各种敌机,子弹什么的都很方便. 在此要感谢开发pygame模块的开发人员,真的很好用(逃 效果图↓ 主函 ...

  5. python3的下载与安装

    python3的下载与安装 1.首先,从Python官方网站:http://python.org/getit/ ,下载Windows的安装包 ython官网有几个下载文件,有什么区别?Python 3 ...

  6. for循环练习题(1 ,判断任意一个数是91的多少倍 2,编写程序实现给定一个整数判断它从0到这个整数中间出现多少次9的次数)

    1 //判断任意一个数是9的多少倍 #include <stdio.h> #include <stdlib.h> int main() { printf("请输入任意 ...

  7. C语言中malloc函数的理解

    在C语言中malloc函数主要是用在堆内存的申请上,使用malloc函数时,函数会返回一个void *类型的值,这个值就是你申请的堆内存的首地址:为什么返回的地址是一个void *类型的地址呢?首先我 ...

  8. 2017Facebook面试题改编“一面砖墙 ”

    题目:一面砖墙 这道题改编自网上Facebook去年的一道面试题,是hihoCoder的1494题(https://hihocoder.com/problemset/problem/1494) 这道题 ...

  9. Lingo解决最优化问题

    目录 Lingo解决优化问题 前言 一.优化模型介绍 二.运输问题 2.1 问题描述 2.2 问题分析 2.2 优化模型构建 2.3 模型求解 2.4 求解结果 三.待更新 Lingo解决优化问题 @ ...

  10. 10、Java并发编程:并发容器之ConcurrentHashMap

    Java并发编程:并发容器之ConcurrentHashMap(转载) 下面这部分内容转载自: http://www.haogongju.net/art/2350374 JDK5中添加了新的concu ...