【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)运算 ...
随机推荐
- Centos7在运行yum命令时出现报错及排查处理过程
1.1 现象描述 Centos系统在正常重启后,运行yum命令安装软件工具的时候出现以下报错: cannot open Packages index using db5 - Structure ne ...
- wusir 面试题答案在老男孩的视频里
注意:你问答案在哪里?答案在视频里了,就是不给你写. 第一部分 Python基础篇(80题) 为什么学习Python? 通过什么途径学习的Python? Python和Java.PHP.C.C#.C+ ...
- linux lvm扩容
1.分区, 查看磁盘使用:fdisk -l 对磁盘分区:fdisk /dev/sdb 2.创建pv pvcreate /dev/sdb1 查看pv: pvdisplay 3.查看vg vgdisp ...
- JMX浅谈
一 JMX 是什么? JMX(Java Management Extensions,即Java管理扩展) JMX在Java编程语言中定义了应用程序以及网络管理和监控的体系结构.设计模式.应用程序接口以 ...
- 用go和zk实现一个简单的分布式server
golang的zk客户端 最近打算写个简单的配置中心,考虑到实现便捷性,语言选择了go,由于其中计划用到zk,就调研了下golang的zk客户端,并实现了个简单的分布式server.最终找到了两个,地 ...
- Android开发——网易云音乐使用的开源组件集合
前言 网易云音乐Android版从第一版使用到现在,全新的 Material Design 界面,更加清新.简洁.同样也是音乐播放器开发者,我们确实需要思考,相同的功能,会如何选择.感谢开源,让我们有 ...
- Wireshark启动出现“无法启动此程序,因为计算机丢失api-ms-win-crt-runtime-l1-1-0.dll。”
由于重装了win7系统,安装wireshark启动出现了“无法启动此程序,因为计算机丢api-ms-win-crt-runtime-l1-1-0.dll”的问题. 网上查了一圈的资料终解决问题,于是整 ...
- windows下,cmd 运行 python 脚本,选中文字就停止运行了【已解决】
参考资料: https://jingyan.baidu.com/article/ce09321bb95dda2bff858f26.html 问题原因: cmd 里面,快速编辑模式会暂停程序 解决步骤: ...
- leetcode 【 Two Sum 】python 实现
题目: Given an array of integers, find two numbers such that they add up to a specific target number. ...
- hnust CZJ-Superman
问题 B: CZJ-Superman 时间限制: 1 Sec 内存限制: 128 MB提交: 636 解决: 87[提交][状态][讨论版] 题目描述 “那是只鸟?那是飞机?那是——超人!” 程序 ...