题意:有n个格子排成一行,其中一些格子里面有字符X。两个游戏者轮流操作,每次可以选一个空格,在里面放上字符X。

如果此时有3个连续的X出现,则该游戏者赢得比赛。初始条件下不会有3个X连续出现。

判断先手胜负情况,若必胜则升序输出先手第一步的所有可选必胜策略

n<=200

思路:如果有XX或者X.X出现则一定先手胜

一个结论:X的旁边和旁边的旁边不能放X

于是整个游戏被不能放X的区域分成了若干个独立的片段,每次都可以选择一个片段进行游戏,就是若干个游戏的和

由于每个棋盘片段都是连续的,想到用一个正整数(即长度)来表示状态,g(x)表示由连续的x个格子组成的棋盘所对应的SG函数值

则有递推方程g(x)=mex(g(x-3),g(x-4),g(x-5),g(1)^g(x-6),g(2)^(x-7)……)

有了g函数,很容易算出初始局面的SG函数,所有使得后继专题SG值为0的决策即为所求

 #include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
typedef long long ll;
using namespace std;
#define N 21000
#define oo 10000000
#define MOD 1000000007 int g[N],flag[N],b[N],c[N],d[N],n;
char a[N]; int isok(int x)
{
int k=;
a[x]='X';
for(int i=;i<=n-;i++)
{
if(a[i]=='X'&&a[i+]=='X'&&a[i-]=='.'){k=i-; break;}
if(a[i]=='X'&&a[i-]=='X'&&a[i+]=='.'){k=i+; break;}
if(a[i]=='.'&&a[i-]=='X'&&a[i+]=='X'){k=i; break;}
}
if(k)
{
a[x]='.';
return ;
}
for(int i=;i<=n;i++) b[i]=;
for(int i=;i<=n;i++)
if(a[i]=='X')
for(int j=-;j<=;j++)
if(i+j>&&i+j<=n) b[i+j]=;
int ans=;
int s=;
for(int i=;i<=n;i++)
if(b[i]==) s++;
else if(s)
{
ans^=g[s];
s=;
}
if(s) ans^=g[s];
a[x]='.';
if(ans) return ;
return ;
} int main()
{
//freopen("uva10561.in","r",stdin);
//freopen("uva10561.out","w",stdout);
g[]=;
g[]=g[]=g[]=;
g[]=g[]=;
for(int i=;i<=;i++)
{
memset(flag,,sizeof(flag));
for(int j=;j<=;j++) flag[g[i-j]]=;
for(int j=;j<=i;j++)
if(i-j>=) flag[g[j-]^g[i-j]]=;
int j=;
while(flag[j]) j++;
g[i]=j;
}
//for(int i=1;i<=200;i++) printf("%d %d\n",i,g[i]);
int cas;
scanf("%d",&cas);
while(cas--)
{
scanf("%s",a+);
n=strlen(a+);
for(int i=;i<=n;i++) d[i]=;
for(int i=;i<=n-;i++)
{
if(a[i]=='X'&&a[i+]=='X'&&a[i-]=='.') d[i-]=;
if(a[i]=='X'&&a[i-]=='X'&&a[i+]=='.') d[i+]=;
if(a[i]=='.'&&a[i-]=='X'&&a[i+]=='X') d[i]=;
}
for(int i=;i<=n;i++) b[i]=;
for(int i=;i<=n;i++)
if(a[i]=='X')
for(int j=-;j<=;j++)
if(i+j>&&i+j<=n) b[i+j]=;
int ans=;
int s=;
for(int i=;i<=n;i++)
if(b[i]==) s++;
else if(s)
{
ans^=g[s];
s=;
}
if(s) ans^=g[s];
s=;
for(int i=;i<=n;i++) s+=d[i];
if(ans||s)
{
printf("WINNING\n");
int m=;
for(int i=;i<=n;i++)
if(a[i]=='.'&&isok(i)) d[i]=;
for(int i=;i<=n;i++)
if(d[i]) c[++m]=i;
for(int i=;i<=m-;i++) printf("%d ",c[i]);
printf("%d\n",c[m]);
}
else
{
printf("LOSING\n");
printf("\n");
}
}
return ;
}

【UVA10561】Treblecross(SG函数)的更多相关文章

  1. UVa 10561 Treblecross (SG函数)

    题意:给定上一行字符串,其中只有 X 和 . 并且没有连续的三个 X,两个玩家要分别在 . 上放 X,如果出现三个连续的 X,则该玩家胜利,现在问你先手胜还是败,如果是胜则输出第一步可能的位置. 析: ...

  2. UVA10561 Treblecross —— SG博弈

    题目链接:https://vjudge.net/problem/UVA-10561 题意: 两个人玩游戏,轮流操作:每次往里面添加一个X,第一个得到XXX的获胜. 题解: 详情请看<训练指南&g ...

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

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

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

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

  5. LightOJ 1229 Treblecross(SG函数打表 + 遍历)题解

    题意:给你一串含“.”和“X”的字串,每次一个玩家可以把‘."变成“X”,谁先弄到三个XXX就赢.假如先手必赢,输出所有能必赢的第一步,否则输出0. 思路:显然如果一个X周围两格有X那么肯定 ...

  6. poj 3575 Crosses and Crosses(SG函数)

    Crosses and Crosses Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 3063   Accepted: 11 ...

  7. HDU 5795 A Simple Nim 打表求SG函数的规律

    A Simple Nim Problem Description   Two players take turns picking candies from n heaps,the player wh ...

  8. 【转】博弈—SG函数

    转自:http://chensmiles.blog.163.com/blog/static/12146399120104644141326/ http://blog.csdn.net/xiaofeng ...

  9. HDU 1848 Fibonacci again and again【SG函数】

    对于Nim博弈,任何奇异局势(a,b,c)都有a^b^c=0. 延伸: 任何奇异局势(a1, a2,… an)都满足 a1^a2^…^an=0 首先定义mex(minimal excludant)运算 ...

随机推荐

  1. 爬虫学习(四)——post请求爬取

    百度翻译爬取数据 import urllib.requestimport urllib.parsepost_url = "https://fanyi.baidu.com/sug"h ...

  2. ceph 性能

    mysql在以下设备备份耗时,供大家参考: 备份文件大小 sata用时 ceph用时 nas挂载sata盘用时 7G   1分钟   15G   2分钟 21分钟 47G   8分钟 82分钟 274 ...

  3. 七、Shell printf 命令

    Shell printf 命令 上一章节我们学习了 Shell 的 echo 命令,本章节我们来学习 Shell 的另一个输出命令 printf. printf 命令模仿 C 程序库(library) ...

  4. 解决国内网络Python2.X 3.X PIP安装模块连接超时问题

    pip国内的一些镜像   阿里云 http://mirrors.aliyun.com/pypi/simple/   中国科技大学 https://pypi.mirrors.ustc.edu.cn/si ...

  5. 服务端Latex解析成图片或者HTML或者SVG方案

    Latex公式表达式在服务端进行转换成可用数据 使用语言与扩展 node.js Mathjax (文档链接) MathJax在nodejs上解决方案 mathjax/MathJax-node(GitH ...

  6. Scrapy-redis分布式爬虫爬取豆瓣电影详情页

    平时爬虫一般都使用Scrapy框架,通常都是在一台机器上跑,爬取速度也不能达到预期效果,数据量小,而且很容易就会被封禁IP或者账号,这时候可以使用代理IP或者登录方式爬,然而代理IP很多时候都很鸡肋, ...

  7. STM32的四种输出模式(转载)

    1.普通推挽输出(GPIO_Mode_Out_PP):   使用场合:一般用在0V和3.3V的场合.线路经过两个P_MOS 和N_MOS 管,负责上拉和下拉电流.   使用方法:直接使用   输出电平 ...

  8. 字符编码笔记:ASCII、Unicode和UTF-8

    1. ASCII码 我们知道,在计算机内部,所有的信息最终都表示为一个二进制的字符串.每一个二进制位(bit)有0和1两种状态,因此八个二进制位就可以组合出256种状态,这被称为一个字节(byte). ...

  9. Bomb HDU - 3555 (数位DP)

    Bomb HDU - 3555 (数位DP) The counter-terrorists found a time bomb in the dust. But this time the terro ...

  10. [BZOJ3312][USACO]不找零(状压DP)

    Description 约翰带着 N 头奶牛在超市买东西,现在他们正在排队付钱,排在第 i 个位置的奶牛需要支付 Ci元.今天说好所有东西都是约翰请客的,但直到付账的时候,约翰才意识到自己没带钱,身上 ...