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算法在搞图论的时候就没搞太懂,以后得找时间深入了解) (以下有关无向图删边游戏的资料来自论文贾志豪<组合游戏 ...
随机推荐
- CODECHEF Oct. Challenge 2014 Children Trips
@(XSY)[分塊, 倍增] Description There's a new trend among Bytelandian schools. The "Byteland Tourist ...
- ApplicationContext介绍
如果说BeanFactory是Spring的心脏,那么ApplicationContext就是完整的身躯了.ApplicationContext由BeanFactory派生而来,提供了更多面向实际应用 ...
- 第四章——SQLServer2008-2012资源及性能监控(1)专家
http://blog.csdn.net/dba_huangzj/article/details/8614817
- 分享tiny4412,emmc烧录u-boot, 支持fastboot模式烧写emmc
转载 : http://www.arm9home.net/read.php?tid-83474.html 本人是第一次在此发帖,希望大家多多支持,发帖目的是为了分享,分享的目的是传递开源的精神.Tin ...
- Linux 嵌入式启动以及优化
转载:http://www.embeddedlinux.org.cn/html/jishuzixun/201312/19-2717.html 第一步: BootLoader -- U boot 1 ...
- python获取对象的信息
Types 判断基本数据类型可以直接写int,str等,但如果要判断一个对象是否是函数怎么办?可以使用types模块中定义的常量. >>> import types >> ...
- Intent 传递对象
方法: 可以让这个要传递的对象所属类实现Serializable或者Parcelable接口, 然后利用onCreate函数中的Bundle参数作为载体,传递这个对象. 例如: <span st ...
- 【windows】windows下的hosts文件位置
- mac下mysqldump找不到命令
之所以会出现MySQL或者mysqldump这样的命令找不到, 我们可以打开/usr/bin文件夹,发现bin目录中并没有mysql打头的UEF文件, 而在/usr/local/mysql/bin中可 ...
- iOS开发 编码规范
转至 http://www.cnblogs.com/celestial/archive/2012/06/30/2571417.html 编码规范 一.文档结构管理 1.建立Libraries文件夹 ...