题意:有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. 算法竞赛入门经典5.1 从c到c++

    这个章节主要是讲述了一些c++的特性,在这里面,对我用处最大的应该就是字符串吧.首先是getline,getchar,stringstream的使用了吧. 首先介绍这三个函数. 1. getline函 ...

  2. 十、Linux vi/vim

    Linux vi/vim 所有的 Unix Like 系统都会内建 vi 文书编辑器,其他的文书编辑器则不一定会存在. 但是目前我们使用比较多的是 vim 编辑器. vim 具有程序编辑的能力,可以主 ...

  3. MVP模式与MVVM模式

    1.mvp模式(Model层 Presenter层 View 层) Model层 :数据层(ajax请求) Presenter层:呈现层,view逻辑相关的控制层,控制层可以去调Model去发ajax ...

  4. JZOJ 4757. 树上摩托

    Description Sherco是一位经验丰富的魔♂法师.Sherco在第零次圣杯战争中取得了胜利,并取得了王之宝藏——王の树.他想把这棵树砍去任意条边,拆成若干棵新树,并装饰在他的摩托上,让他的 ...

  5. JZOJ 3461. 【NOIP2013模拟联考5】小麦亩产一千八(kela)

    3461. [NOIP2013模拟联考5]小麦亩产一千八(kela) (Standard IO) Time Limits: 1000 ms  Memory Limits: 262144 KB  Det ...

  6. HDU - 1054 Strategic Game (二分图匹配模板题)

    二分图匹配模板题 #include <bits/stdc++.h> #define FOPI freopen("in.txt", "r", stdi ...

  7. 01-Flutter移动电商实战-项目学习记录

    一直想系统性的学习一下 Flutter,正好看到该课程<Flutter移动电商实战>的百度云资源,共 69 课时,由于怕自己坚持不下去(经常学着学着就不学了),故采用博客监督以记之. 1. ...

  8. 第八届蓝桥杯C/C++ B组省赛----分巧克力

    分巧克力 问题描述 儿童节那天有K位小朋友到小明家做客.小明拿出了珍藏的巧克力招待小朋友们. 小明一共有N块巧克力,其中第i块是Hi x Wi的方格组成的长方形. 为了公平起见,小明需要从这 N 块巧 ...

  9. easyui-combogrid必填为空时无法通过表单验证的问题

    在使用easyui-combogrid时,由于html解析出的格式是如下三层: <td> <input id="txcombo" class="easy ...

  10. C++编程规范(101条准则)

    记录学习,方便以后查看.  2014-12-28 看完这本书,但是我做到的又有多少呢?确实有一部分 0 不要拘泥于小节 1 在高警告级别干净利落的进行编译,不放过任何警告 2 使用自动构建系统 3 使 ...