题目链接: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. [AI开发]深度学习如何选择GPU?

    机器推理在深度学习的影响下,准确性越来越高.速度越来越快.深度学习对人工智能行业发展的贡献巨大,这得益于现阶段硬件计算能力的提升.互联网海量训练数据的出现.本篇文章主要介绍深度学习过程中如何选择合适的 ...

  2. android 扩大view的响应区域

    1.Android提供TouchDelegate帮助实现扩大一个很小的view的点击区域 例如:https://developer.android.com/training/gestures/view ...

  3. Linux环境下编译JDK

    环境准备 操作系统,ubuntu-14.04.6-desktop-amd64.iso,下载地址:http://59.80.44.100/releases.ubuntu.com/14.04/ubuntu ...

  4. 邁向IT專家成功之路的三十則鐵律 鐵律二十二:IT人升遷之道-無為

    升遷管道是許多人求職時相當重要的考量之一,畢竟人除了很愛錢之外更愛顯赫的頭銜,然而在企業中越顯赫的頭銜,其背後通常有更多的罵名,因為許多人的高官厚爵都是踩著一群人的頭頂爬上去的,隨時哪一天跌了下來,都 ...

  5. nodeJS一些事儿

    node-webkit:开发桌面+WEB混合型应用的神器[大漠穷秋] 展望未来 其实这条路老早就有人在走 网上有很多人在争论,未来究竟是原生的应用会胜出,还是WEB APP会胜出,实际上这两者并不是你 ...

  6. scala工具sbt的安装和使用;idea如何创建scala项目

    scala的sbt类似于java的maven mac:brew install sbt linux:yum Install sbt 或者下载二机制包 使用sbt需要想mvn一样搭建公司私服,不然,下载 ...

  7. 【Nginx】事件驱动框架和异步处理

    Nginx对请求的处理是通过事件触发的,模块作为事件消费者,仅仅能被事件收集.分发器调用.这与传统的Webserver是不同的. 传统的Webserver下,一个请求由一个进程消费.请求在建立连接后将 ...

  8. python3 查看已安装的模块

    一.命令行下使用pydoc命令 在命令行下运行$ pydoc modules即可查看 二.在python交互解释器中使用help()查看 在交互式解释器中输入>>> help(&qu ...

  9. PS 如何制作WIN7的玻璃化透明窗口效果

    1 绘制一个圆角矩形,并将不透明度设为16%以及添加投影效果   2 再次添加外发光效果   3 新建一个图层,再填充一下这个圆角矩形(可以填充为任意颜色,只要和别的颜色区分开来)   4 选中这个区 ...

  10. IOS_DatePicker_PickerView_SegmentControl_键盘处理

    H:/0712/01_UIController_MJViewController.m // MJViewController.m // 01-总结复习 // Created by apple on 1 ...