UVA10561 Treblecross —— SG博弈
题目链接: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博弈的更多相关文章
- UVA12293 Box Game —— SG博弈
题目链接:https://vjudge.net/problem/UVA-12293 题意: 两人玩游戏,有两个盒子,开始时第一个盒子装了n个球, 第二个盒子装了一个球.每次操作都将刷量少的盒子的球倒掉 ...
- UVA1482 Playing With Stones —— SG博弈
题目链接:https://vjudge.net/problem/UVA-1482 题意: 有n堆石子, 每堆石子有ai(ai<=1e18).两个人轮流取石子,要求每次只能从一堆石子中抽取不多于一 ...
- HDU 1848(sg博弈) Fibonacci again and again
Fibonacci again and again Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Jav ...
- UVA10561 Treblecross 组合游戏/SG定理
Treblecross is a two player gamewhere the goal is to get three X in a row on a one-dimensional board ...
- UVA 10561 - Treblecross(博弈SG函数)
UVA 10561 - Treblecross 题目链接 题意:给定一个串,上面有'X'和'.',能够在'.'的位置放X.谁先放出3个'X'就赢了,求先手必胜的策略 思路:SG函数,每一个串要是上面有 ...
- uva10561 - Treblecross
Treblecross is a two player game where the goal is to get three `X' in a row on a one-dimensional bo ...
- hdu 1851(A Simple Game)(sg博弈)
A Simple Game Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/65535 K (Java/Others)Tot ...
- HDU 1536 S-Nim SG博弈
S-Nim Problem Description Arthur and his sister Caroll have been playing a game called Nim for som ...
- POJ 3710 Christmas Game#经典图SG博弈
http://poj.org/problem?id=3710 (说实话对于Tarjan算法在搞图论的时候就没搞太懂,以后得找时间深入了解) (以下有关无向图删边游戏的资料来自论文贾志豪<组合游戏 ...
随机推荐
- Remove Nth Node From End of List(链表,带测试代码)
Given a linked list, remove the nth node from the end of list and return its head. For example, Give ...
- asp .net 为图片添加图片水印 .
首先写好一个写入图片水印的类,先创建一个ImageWriter类库 (该类中有包含枚举类型和方法) using System; using System.Collections.Generic; ...
- Solaris 系统启动与关闭
忘掉root密码 更改内核参数后,重启进不了系统 复制---进入单用户模式----恢复文件 系统突然死机,如何尽量减少数据丢失 Sync 同步命令.将内存内容输入到硬盘,相当于保存文档. Unix ...
- xammp 配置虚拟主机
## This is the main Apache HTTP server configuration file. It contains the# configuration directives ...
- python(1)- 初识python
一.了解编程语言 1.编程语言的定义 编程语言即语言,语言的本质就是沟通,因而编程语言与英语 .法语.日语等所有语言并无区别,只不过英语是人与人之间沟通的介质,而编程语言则是程序员与计算机沟通的介质. ...
- Android SQLite性能分析
作为Android预置的数据库模块,对SQLite的深入理解是很有必要的,能够从中找到一些优化的方向. 这里对SQLite的性能和内存进行了一些測试分析.对照了不同操作的运行性能和内存占用的情况,粗略 ...
- Tomcat服务器改主页 & jeesite框架改首页
Tomcat服务器改主页: 方法一: 把原来的 ROOT 目录清空: 发布你自己的项目到 ROOT 目录下: 发布程序 /webapps/ROOT/WEB-INF/web.xml 中需要有默认首页定义 ...
- NTAG 标签
NTAG 标签 这里描述针对 NTAG213.而 NTAG215/216只是容量不同,其它功能都一样.  UID UID 有 7 bytes.上图中有 9 bytes 的 serial number ...
- git 安装及命令
一.window下的git安装 1.安装教程 网上教程一堆.我參考的是这个:Git_Windows 系统下Git安装图解 还有这个也不错 2.环境搭建: 在配置完毕后,自己主动载入到系统环境变量中.如 ...
- 解读OC中的load和initialize
在 Objective-C 中,NSObject 是绝大多数类的基类.而在 NSObject 中有两个类方法 load 和 initialize,那这两个方法是在什么时机被调用呢?父类.Categor ...