uva10561 - Treblecross SG定理
来源:互联网 发布:数码宝贝2知乎 编辑:程序博客网 时间:2024/06/06 12:36
Treblecross
Input: Standard Input
Output: Standard Output
Time Limit: 4 Seconds
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 next to each other, that player wins.
Given the current state of the game, you are todetermine if the player to move can win the game assuming both players playperfectly. If so, you should also print all moves that will eventually lead toa win.
Consider the game where the board size is 5cells. If the first player puts a X at position three (in the middle) so thestate becomes ..X.., he will win the game as no matter where the other playerputs his X, the first player can get three X in a row. If, on the other hand,the first player puts the X in any other position, the second player will winthe game by putting the X in the opposite corner (for instance, after thesecond player moves the state might be .X..X). This will force the first playerto put an X in a position so the second player wins in the next move.
Input
The input begins with an integer N (N<100),the number of states that will follow. Each state is represented by a string ona line by itself. The string will only contain the characters '.' and 'X'. Thelength of the string (the size of the board) will be between 3 and 200characters, inclusive. No state will contain three X in a row.
Output
For each case, first output WINNING or LOSING depending onif the player to move will win or lose the game. On the next line, output inincreasing order all positions on the board where the player to move may put anX and win the game. The positions should be separated by a blank, and be inincreasing order. The leftmost position on the board is 1.
SampleInput Outputfor Sample Input
4
.....
X.....X..X.............X....X..X
.X.X...X
...............................................
WINNING
3
LOSING
WINNING
3
WINNING
1 12 15 17 20 24 28 31 33 36 47
N个格子排成一行,里面有些是X,两个人轮流往空的地方放X,如果出现连续3个X,那个人获胜,。如果能获胜,输出必胜方案的第一步。
我最开始想的是递归子状态的SG,可能是因为X位置问题,不能表示状态。。
其实完全可以先求出所有地方都是空的SG,sg[n]表示连续连续n个空的SG值。那样对于某种状态,只要在把它能放X的段的SG全部异或就行了。
#include<iostream>#include<queue>#include<cstring>#include<cstdio>#include<cmath>#include<set>#include<map>#include<vector>#include<stack>#include<algorithm>#define eps 1e-9#define MAXN 210#define MAXM 110#define MOD 100000007typedef long long LL;using namespace std;int T,sg[MAXN],g[MAXN];char str[MAXN];vector<int> ans;int win(){ int L=strlen(str); for(int i=0;i<L-2;i++) if(str[i]=='X'&&str[i+1]=='X'&&str[i+2]=='X') return 0; int no[MAXN]={0}; for(int i=0;i<L;i++) if(str[i]=='X'){ for(int d=-2;d<=2;d++) if(i+d>=0&&i+d<L){ if(d&&str[i+d]=='X') return 1; //1不一定表示这个状态的SG,SG有可能更大。反正这道题只要有SG大于0就可以 no[i+d]=1; } } no[L]=1; int start=-1,SG=0; for(int i=0;i<=L;i++){ if(start<0&&!no[i]) start=i; if(no[i]){ if(start>=0) SG^=sg[i-start]; start=-1; } } return SG;}int mex(vector<int>& s){ if(s.empty()) return 0; sort(s.begin(),s.end()); if(s[0]) return 0; int L=s.size(); for(int i=1;i<L;i++) if(s[i]>s[i-1]+1) return s[i-1]+1; return s[L-1]+1;}void init(){ sg[0]=0; sg[1]=sg[2]=sg[3]=1; for(int i=4;i<MAXN;i++){ vector<int> s; s.push_back(sg[i-3]); s.push_back(sg[i-4]); if(i>=5) s.push_back(sg[i-5]); for(int j=3;j<i-3;j++) s.push_back(sg[j-2]^sg[i-j-3]); sg[i]=mex(s); }}int main(){ freopen("in.txt","r",stdin); init(); scanf("%d",&T); while(T--){ scanf("%s",str); ans.clear(); int sum=win(); if(!win()){ printf("LOSING\n\n"); continue; } for(int i=0;i<strlen(str);i++) if(str[i]=='.'){ str[i]='X'; if(!win()) ans.push_back(i+1); str[i]='.'; } int L=ans.size(); if(L){ printf("WINNING\n"); int first=1; for(int i=0;i<L;i++){ if(first) first=0; else printf(" "); printf("%d",ans[i]); } puts(""); } else printf("LOSING\n"); } return 0;}
- uva10561 - Treblecross SG定理
- uva10561 博弈 Treblecross 组合游戏/SG定理
- [UVA10561] Treblecross && 博弈 SG函数
- Treblecross UVA10561
- uva10561 Treblecross
- UVA 10561 Treblecross 组合游戏/SG定理
- UVA - 10561 Treblecross (SG定理)
- uva10561(SG函数)
- uva 10561 Treblecross (SG函数)
- UVA 10561 - Treblecross(博弈SG函数)
- (SG博弈)uva 10561 - Treblecross
- 【UVA 10561】 Treblecross|博弈论|SG函数
- SG函数(Treblecross游戏,UVA 10561)
- SG定理
- SG定理
- UVA - 10561 Treblecross (博弈数学&SG函数)
- 博弈SG定理模板
- UVA 10561 Treblecross(组合游戏_SG定理的应用)
- 21天学通Java学习笔记-Day12(MYsql-JDBC)
- 使用scipy进行聚类
- struts.xml中package的namespace属性
- 访问google的办法之一
- obj-c编程17:键值观察(KVO)
- uva10561 - Treblecross SG定理
- 数据库中视图的作用
- C++中delete和delete[]的区别
- poj 2051 Argus(优先队列)
- leetcode Jump Game II
- error:fgetc函数无法获取文本文档中的内容
- DDL引发的对象invalidation
- 【android开发笔记】如何让ImageButton去掉白色边框和让ImageButton具有点击效果
- 从头开始写项目Makefile(零):前言