【UVA10561】Treblecross(SG函数)
题意:有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函数)的更多相关文章
- UVa 10561 Treblecross (SG函数)
题意:给定上一行字符串,其中只有 X 和 . 并且没有连续的三个 X,两个玩家要分别在 . 上放 X,如果出现三个连续的 X,则该玩家胜利,现在问你先手胜还是败,如果是胜则输出第一步可能的位置. 析: ...
- UVA10561 Treblecross —— SG博弈
题目链接:https://vjudge.net/problem/UVA-10561 题意: 两个人玩游戏,轮流操作:每次往里面添加一个X,第一个得到XXX的获胜. 题解: 详情请看<训练指南&g ...
- 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函数,每一个串要是上面有 ...
- LightOJ 1229 Treblecross(SG函数打表 + 遍历)题解
题意:给你一串含“.”和“X”的字串,每次一个玩家可以把‘."变成“X”,谁先弄到三个XXX就赢.假如先手必赢,输出所有能必赢的第一步,否则输出0. 思路:显然如果一个X周围两格有X那么肯定 ...
- poj 3575 Crosses and Crosses(SG函数)
Crosses and Crosses Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 3063 Accepted: 11 ...
- HDU 5795 A Simple Nim 打表求SG函数的规律
A Simple Nim Problem Description Two players take turns picking candies from n heaps,the player wh ...
- 【转】博弈—SG函数
转自:http://chensmiles.blog.163.com/blog/static/12146399120104644141326/ http://blog.csdn.net/xiaofeng ...
- 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)运算 ...
随机推荐
- BZOJ2023: [Usaco2005 Nov]Ant Counting 数蚂蚁(dp)
题意 题目描述的很清楚... 有一天,贝茜无聊地坐在蚂蚁洞前看蚂蚁们进进出出地搬运食物.很快贝茜发现有些蚂蚁长得几乎一模一样,于是她认为那些蚂蚁是兄弟,也就是说它们是同一个家族里的成员.她也发现整个 ...
- mysql切换数据库提示警告:Reading table information for completion of table and column names
登录数据库后,选择数据库时发现以下提示, mysql> use testReading table information for completion of table and column ...
- vmware 开机自动启动
vmware开机自动启动, 可以使用vmrun命令. 1. 首先在“我的电脑”-“属性”-“高级”-“环境变量”-“PATH”中添加vmware路径,如:C:\Program Files (x86)\ ...
- 基于django的个人博客网站建立(三)
基于django的个人博客网站建立(三) 前言 网站效果可点击这里访问 今天主要完成的是文章在页面的显示以及评论,留言 具体内容 首先我希望主页面是显示我的所有文章,于是在主页面的视图函数中返回了所有 ...
- Zookeeper协调服务系统·ELK日志管理系统简介
Zookeeper协调服务系统: 说明:它分布式系统中的协调服务系统,是Hadoop下的一个子项目,可提供的服务有:名字服务.配置服务.分布式同步.组服务等. 3个角色:Leaders.Follow. ...
- B1061 判断题 (15分)
B1061 判断题 (15分) 判断题的评判很简单,本题就要求你写个简单的程序帮助老师判题并统计学生们判断题的得分. 输入格式: 输入在第一行给出两个不超过 100 的正整数 N 和 M,分别是学生人 ...
- UVA - 753 A Plug for UNIX(网络流)
题意 给定一些插头设备和插座,有一些方法可以把其中一些插头变成另一种插头.求无法匹配插座的插头设备个数. 题解 用\(map\)给每个字符串标号为\(a_i\)和\(b_i\). 读入每种改变插头的方 ...
- [USACO]Bovine Genomics
Description 给定两个字符串集合A,B,均包含N个字符串,长度均为M,求一个最短的区间[l,r],使得不存在字符串\(a\in A,b\in B,\)且\(a[l,r]=b[l,r]\) , ...
- 笔记-python-反射
笔记-python-反射 1. 反射 在很多地方看到自省和反射,很晕菜,整理了一下相关文档,加深了理解. 自省和反射其实说的是一件事,核心操作是根据输入去对象(模块)中调用(查找/获取/删除/添加)成 ...
- 16,Python网络爬虫之Scrapy框架(CrawlSpider)
今日概要 CrawlSpider简介 CrawlSpider使用 基于CrawlSpider爬虫文件的创建 链接提取器 规则解析器 引入 提问:如果想要通过爬虫程序去爬取”糗百“全站数据新闻数据的话, ...