博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UVA10561 Treblecross 组合游戏/SG定理
阅读量:4348 次
发布时间:2019-06-07

本文共 3882 字,大约阅读时间需要 12 分钟。

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

 

 

题意:给定一个串,上面有'X'和'.',可以在'.'的位置放X,谁先放出3个'X'就赢了,求先手必胜的策略

题解:SG函数,每个串要是上面有一个X,周围的4个位置就是禁区了(放下去必败),所以可以以X分为几个子游戏去求SG函数的异或和进行判断,至于求策略,就是枚举每个位置就可以了

#include
#define N 250#define mes(x) memset(x, 0, sizeof(x));#define ll __int64const long long mod = 1e9+7;const int MAX = 0x7ffffff;using namespace std;int SG[N], dir[N], a[N], l;char s[N];int f(){ int num, i, ans; for(ans=num=i=0;i<=l;i++) if(!a[i]) num++; else{ ans ^= SG[num]; num = 0; } return ans;}void getsg(){ int n, x, j; SG[0] = 0; SG[1] = SG[2] = SG[3] = 1; for(n=4;n<=200;n++){ mes(dir); for(x=n-5;x<=n-3;x++) if(x>=0) dir[SG[x]] = 1; for(x=1;n-5-x>=0;x++) dir[SG[x]^SG[n-5-x]] = 1; for(j=0;;j++){ if(!dir[j]){ SG[n] = j; break; } } }}int main(){ int T, i, flag, j; getsg(); scanf("%d", &T); while(T--){ scanf("%s", s); l = strlen(s); if(strstr(s,"X.X")||strstr(s, "XX")){ mes(dir); printf("WINNING\n"); for(i=0;i
= 1) dir[i-1] = 1; } } if(s[l-1] == 'X'&& s[l-2] == 'X') dir[l-3] = 1; for(flag=i=0;i<200;i++) if(dir[i]){ printf("%s%d", flag?" ":"", i+1); flag = 1; } printf("\n"); } else{ mes(dir); for(i=0;i
=0) dir[j] = 1; memcpy(a, dir, sizeof(a)); a[l] = 1; if(!f()){ printf("LOSING\n\n"); continue; } printf("WINNING\n"); for(flag=1,i=0;i
=0) a[j] = 1; if(!f()){ printf("%s%d", flag?"":" ", i+1); flag = 0; } } } printf("\n"); } }}

 

转载于:https://www.cnblogs.com/Noevon/p/6241175.html

你可能感兴趣的文章
oracle 查询基础
查看>>
C++与C#的时间转换
查看>>
SeekBar: 修改SeekBar中进度条的高度
查看>>
js与jquery间的区别
查看>>
生成随机密码的工具类
查看>>
Ubuntu18.04 搭建zookeeper单机版集群
查看>>
阿里巴巴技术论坛总结
查看>>
匀速运动
查看>>
编写一个函数,计算两个数字的和差积商
查看>>
Input 只能输入数字与小数点
查看>>
使用TortoiseSVN打小包-补丁升级包-覆盖更新-增量发布
查看>>
[luogu4459][BJOI2018]双人猜数游戏(DP)
查看>>
Map 地图
查看>>
Visual studio 2008下用SWIG包裹C/C++代码给Perl调用(Windows XP)
查看>>
处理html转码
查看>>
设计模式之观察者模式
查看>>
(零)TCP/IP详解综述
查看>>
u盘中毒后文件被隐藏了
查看>>
Mysql用户管理
查看>>
今日笔记
查看>>