UVa10561 Treblecross

博弈 sg函数

如果能一步取胜的话,直接扫一遍,找出所有能一步取胜的位置输出。

否则枚举放‘X’的位置,计算剩下空区间的SG函数的异或和,若为0,则该位置可以作为答案。

计算空区间时要刨去X旁边的两个空(放在这里必败) 例如.X.....X.这一区段的可用长度为3

SG函数的预处理还不太理解

↓那个pd()并没有用到

  1 /*by SilverN*/
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<cmath>
  7 using namespace std;
  8 const int mxn=210;
  9 char s[mxn];
 10 int n,f[mxn];
 11 inline bool pd(){
 12     for(int i=2;i<n;i++){
 13         if(s[i-1]==‘X‘ && s[i]==‘X‘ && s[i+1]==‘X‘)return 1;
 14     }
 15     return 0;
 16 }
 17 inline bool check(int pos){
 18     if(s[pos+1]==‘X‘){
 19         if(s[pos-1]==‘X‘ || s[pos+2]==‘X‘)return 1;
 20     }
 21     else if(s[pos-1]==‘X‘){
 22         if(pos>2 && s[pos-2]==‘X‘)return 1;
 23     }
 24     return 0;
 25 }
 26 inline bool ar(int p){
 27     for(int i=max(1,p-2);i<=p+2;i++)if(s[i]==‘X‘)return 1;
 28     return 0;
 29 }
 30 bool calc(){
 31     int i,j,len=0;
 32     int res=0;
 33     for(i=1;i<=n;i++){
 34         if(ar(i)){
 35             res^=f[len]; len=0;
 36         }
 37         else len++;
 38     }
 39     res^=f[len];
 40     return res;
 41 }
 42 int ans[mxn],cnt=0;
 43 void solve(){
 44     cnt=0;
 45     int i,j;
 46     for(i=1;i<=n;i++){
 47         if(s[i]!=‘.‘)continue;
 48         if(check(i)){
 49             for(j=i;j<=n;j++)
 50                 if(s[j]==‘.‘ && check(j)){ans[++cnt]=j;}
 51             return;
 52         }
 53     }
 54     if(calc()){
 55         for(i=1;i<=n;i++){
 56             if(!ar(i)){
 57                 s[i]=‘X‘;
 58                 if(!calc()){
 59                     ans[++cnt]=i;
 60                 }
 61                 s[i]=‘.‘;
 62             }
 63         }
 64     }
 65     return;
 66 }
 67 int vis[mxn];
 68 void init(){//处理sg函数
 69     int i,j,x;
 70     f[1]=f[2]=1;
 71     for(i=3;i<mxn;i++){
 72         memset(vis,0,sizeof vis);
 73         for(j=1;j*2<=i+1;j++){
 74             x=f[i-j-2];//去掉边界两个空位
 75             if(j>3)x^=f[j-3];
 76             vis[x]=1;
 77         }
 78         for(j=0;;j++){if(!vis[j]){f[i]=j;break;}}
 79     }
 80     return;
 81 }
 82 int main(){
 83     int T;scanf("%d",&T);
 84     init();
 85     while(T--){
 86         memset(s,0,sizeof s);
 87         scanf("%s",s+1);
 88         n=strlen(s+1);
 89         solve();
 90         if(cnt){
 91             printf("WINNING\n");
 92             for(int i=1;i<cnt;i++){
 93                 printf("%d ",ans[i]);
 94             }
 95             printf("%d\n",ans[cnt]);
 96         }
 97         else printf("LOSING\n\n");
 98     }
 99     return 0;
100 }
时间: 2024-08-09 07:52:41

UVa10561 Treblecross的相关文章

《算法竞赛入门经典——训练指南》第二章题库

UVa特别题库 UVa网站专门为本书设立的分类题库配合,方便读者提交: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=442 注意,下面注有"extra"的习题并没有在书中出现,但在上面的特别题库中有,属于附加习题. 基础练习 (Basic Problems) UVa11388 GCD LCM UVa11889 Benefit UVa10943 How do y

Treblecross 博弈SG值

Treblecross is a two player game where the goal is to get three X in a row on a one-dimensional board. At the start of the game all cells in the board are empty. In each turn a player puts an X in an empty cell, and if the move results three X next t

UVA 10561 - Treblecross(博弈SG函数)

UVA 10561 - Treblecross 题目链接 题意:给定一个串,上面有'X'和'.',可以在'.'的位置放X,谁先放出3个'X'就赢了,求先手必胜的策略 思路:SG函数,每个串要是上面有一个X,周围的4个位置就是禁区了(放下去必败),所以可以以X分为几个子游戏去求SG函数的异或和进行判断,至于求策略,就是枚举每个位置就可以了 代码: #include <stdio.h> #include <string.h> #include <algorithm> usi

uva 10561 - Treblecross(Nim)

题目链接:uva 10561 - Treblecross 题目大意:n个格子排成一排,其中一些格子有'X',两个游戏者轮流操作,在格子中放X,如果此时出现连续3个X,则获胜.给出先手是否可以取胜,取胜方案的第一步该怎么走. 解题思路:一个X可以导致左右两个的两个格子都不能再放X,因为如果出现XX...XX.X.X,那么下一个人肯定胜利.所以对于长度为n的格子序列,g(x)=maxg(x?3),g(x?4)...g(2)XORg(n?7). 所以可以预先处理出g数组,然后对于给定的序列,枚举先手下

UVa10561

10561 TreblecrossTreblecross is a two player game where the goal is to get three ‘X’ in a row on a one-dimensional board.At the start of the game all cells in the board is empty. In each turn a player puts a ‘X’ in an emptycell, and if that results i

UVA - 10561 Treblecross (SG定理)

Treblecross is a two player gamewhere the goal is to get three X in a row on a one-dimensional board. At the startof the game all cells in the board is empty. In each turn a player puts a X in an empty cell, and if that results in there beingthree X

Treblecross

Treblecross is a two player game where the goal is to get three ‘X’ in a row on a one-dimensional board.At the start of the game all cells in the board is empty. In each turn a player puts a ‘X’ in an emptycell, and if that results in there being thr

Treblecross(uva 10561)

题意:一个 1 × n 的棋盘,有 X 和 :,当棋盘上出现三个连续的X 时游戏结束,两人轮流操作,每次能把一个 : 变成 X,问先手必胜方案数以及先手可以放的位置. /* 对于先手,当有一个'X'时,它周围的两个格子就都不能放'X'了,所以这样游戏就被分成了几个部分,据此设定SG函数. */ #include<iostream> #include<cstdio> #include<cstring> #define N 210 using namespace std;

UVA 10561 Treblecross(博弈论)

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=32209 [思路] 博弈论. 根据X分布划分禁区,每个可以放置的块为单独一个游戏.按长度定义状态,构造sg函数.依次试验每一种放法. [代码] 1 #include<cstdio> 2 #include<vector> 3 #include<cstring> 4 #include<algorithm> 5 using names