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

题意:

两个人玩游戏,轮流操作:每次往里面添加一个X,第一个得到XXX的获胜。

题解:

详情请看《训练指南》P139,以及代码注释。

代码如下:

 #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 = 1e3+; int SG[MAXN], vis[MAXN];
bool hav[MAXN]; //是否有‘X' void getSG() //SG[Len]:'.'连续长度为Len时,往其中放一个'X'的游戏的SG值。
{
SG[] = ; //长度为0时,没有后继状态,故SG[0] = mex{} = 0;
//长度为1、2、3时的后继状态为0, 故SG[1/2/3] = mex{SG[0]} = 1,之所以单独拿出来,是因为
//他们的求法与后面的不一样。
SG[] = SG[] = SG[] = ;
for(int Len = ; Len<MAXN; Len++)
{
memset(vis, , sizeof(vis));
for(int pos = ; pos<=(Len+)/; pos++)
{
//当放了一个'X'进去之后,原先的游戏因为禁区的出现而可能被分为两个子游戏。
int val = SG[Len-pos-];
if(pos>) val ^= SG[pos-];
vis[val] = ;
}
for(int j = ;;j++) if(!vis[j]){
SG[Len] = j;
break;
}
}
} int len, ans[MAXN];
bool oneHit(int pos) //判断在pos位置能否放置一个X然后赢得游戏
{
if(hav[pos]) return ;
if(pos<=len-&&hav[pos+]&&hav[pos+]) return ;
if(pos>=&&hav[pos-]&&hav[pos-]) return ;
if(pos!=&&pos!=len&&hav[pos-]&&hav[pos+]) return ;
return ;
} bool prohibit(int pos) //判断pos是否在禁区之内
{
return hav[pos]||(pos>=&&hav[pos-])||(pos>=&&hav[pos-])||
(pos<=len-&&hav[pos+])||(pos<=len-&&hav[pos+]);
} int getVAL() //得到整个游戏的SG异或和
{
int val = , L = ;
for(int i = ; i<=len; i++)
{
if(prohibit(i)) val ^= SG[L], L = ;
else L++;
}
val ^= SG[L];
return val;
} void solve()
{
ans[] = ;
for(int i = ; i<=len; i++) if(oneHit(i)) { //首先判断先手是否能“一击毙命”
ans[++ans[]] = i;
for(++i; i<=len; i++)
if(oneHit(i)) ans[++ans[]] = i;
return;
}
if(getVAL()) //否则,则利用SG来判断输赢
{
for(int i = ; i<=len; i++) if(!prohibit(i)){
hav[i] = true; //因为先手处于必胜状态,当先手走了一步之后,就轮到后手处于必败状态。
if(!getVAL()) ans[++ans[]] = i;
hav[i] = false;
}
}
} char str[MAXN];
int main()
{
getSG();
int T;
scanf("%d", &T);
while(T--)
{
scanf("%s", str+);
len = strlen(str+);
memset(hav, , sizeof(hav));
for(int i = ; i<=len; i++)
hav[i] = (str[i]=='X'); solve();
if(!ans[])
printf("LOSING\n\n");
else
{
printf("WINNING\n");
for(int i = ; i<ans[]; i++)
printf("%d ", ans[i]);
printf("%d\n", ans[ans[]]);
}
}
}

UVA10561 Treblecross —— SG博弈的更多相关文章

  1. UVA12293 Box Game —— SG博弈

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

  2. UVA1482 Playing With Stones —— SG博弈

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

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

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

  4. UVA10561 Treblecross 组合游戏/SG定理

    Treblecross is a two player gamewhere the goal is to get three X in a row on a one-dimensional board ...

  5. UVA 10561 - Treblecross(博弈SG函数)

    UVA 10561 - Treblecross 题目链接 题意:给定一个串,上面有'X'和'.',能够在'.'的位置放X.谁先放出3个'X'就赢了,求先手必胜的策略 思路:SG函数,每一个串要是上面有 ...

  6. uva10561 - Treblecross

    Treblecross is a two player game where the goal is to get three `X' in a row on a one-dimensional bo ...

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

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

  8. HDU 1536 S-Nim SG博弈

    S-Nim Problem Description   Arthur and his sister Caroll have been playing a game called Nim for som ...

  9. POJ 3710 Christmas Game#经典图SG博弈

    http://poj.org/problem?id=3710 (说实话对于Tarjan算法在搞图论的时候就没搞太懂,以后得找时间深入了解) (以下有关无向图删边游戏的资料来自论文贾志豪<组合游戏 ...

随机推荐

  1. Uoj #350. 新年的XOR

    前缀异或和是可以讨论的,非常naive,然后这就是个水题了23333 #include<bits/stdc++.h> #define ll long long using namespac ...

  2. 用Java做一个跳一跳辅助

    Java跳一跳辅助 首先..让大家看下效果: 由于是闲着没事写的.也懒得看OpenCV的API了. 要用到的工具如下: adb+jdk 把adb添加到环境变量里就行.很简单. 全部代码如下.就这么多. ...

  3. Zab算法详解

    Zookeeper使用了一种称为Zab(Zookeeper Atomic Broadcast)的协议作为其一致性复制的核心,据其作者说这是一种新发算法,其特点是充分考虑了Yahoo的具体情况:高吞吐量 ...

  4. 转:PHP 生成复杂JSON格式 简单快速方法

    PHP 生成JSON 格式主要使用json_encode()函数.这个函数的输入参数支持PHP数组和对象类型. 查阅网上的例子通常都是使用数组的,也有个别使用对象生成.但实际项目中,我们要生成的JSO ...

  5. 邁向IT專家成功之路的三十則鐵律 鐵律二十三:IT人的成家之道-樸實

    根據內政部一份2013年最新的調查報告指出台灣人的離婚率位居全球第三,想想看如果這是經濟成長率的排名表現那該有多好.然而究竟為何在台灣這塊小小的土地上,不僅離婚非常高而且晚婚的人也非常的多,其原因肯定 ...

  6. cocos2d-x step by step(1) First Blood

    下了cocos2d-x 源码,开搞! 首先,笔者本身 1)      5年没有摸过c++了 2)     没用过cocos2d-x 3)      有强烈的求知欲望(这条每个简历个人介绍不都这么写么, ...

  7. 第八讲_图像问答Image Question Answering

    第八讲_图像问答Image Question Answering 课程结构 图像问答的描述 具备一系列AI能力:细分识别,物体检测,动作识别,常识推理,知识库推理..... 先要根据问题,判断什么任务 ...

  8. pycharm pull到github

    1.setting中找到github 正确输入邮箱密码,勾上ssh 2.在本机中git bash 得到ssh代码 输入到github 个人setting中 3.在pycharm中setting项git ...

  9. Objective C block背后的黑魔法

    前言 block在Objective C开发中应用非常广泛,我们知道block会捕获外部对象,也知道使用block要防止循环引用. "知其然而不知其所以然"是一件非常痛苦的事情,那 ...

  10. 命令行查看w3wp进程信息

    用windbg.mdbg等调试器调试时,当出现多个w3wp进程并且用户名相同,需要区分每个w3wp进程对应的PID(进程ID)和应用程序池信息. 我们用以下方式得到每个w3wp进程的详细信息. Win ...