您的位置:首页 > 其它

uva10561(博弈)

2015-07-26 15:52 429 查看
题意:

给出一个串,由X和.构成;

我们可以在.的地方放X,谁先放出三个连续的X获胜;

思路:

首先,如果存在"XX"或者"X.X"那先手必胜;

所以我们肯定不能下出这种情况;所以当一个位置有X时,那么它周围4个点就都不能放,一放就会出现上面的情况;

所以可以以X来把整个游戏变成几个子游戏;就是分成几块安全的区域,然后求每块的sg值;

然后有几种方式,就可以枚举所有可以放的点,看看能不能赢就行;

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;

const int N = 205;
int t, res
, way, len, sg
;
char str
;

int judge() {
for (int i = 0; i < len - 2; i++) {
if (str[i] == 'X' && str[i + 1] == 'X' && str[i + 2] == 'X')
return true;
}
return false;
}

int SG(int x) {
int vis
;
int i, t;
if (sg[x] != -1) return sg[x];
if (x == 0) return sg[x] = 0;
memset(vis, false, sizeof(vis));
for (int i = 1; i <= x; i++) {
int t = SG(max(0, i - 3))^SG(max(0, x - i - 2));
vis[t] = true;
}
for (int i = 0; i < N; i++) {
if (vis[i]) continue;
return sg[x] = i;
}
}

int GetRes() {
for (int i = 0; i < len; i++) {
if (str[i] == '.') {
str[i] = 'X';
if (judge()) {
str[i] = '.';
return false;
}
str[i] = '.';
}
}
int ans = 0, num = 0;
for (int i = 0; i < len; i++) {
if (str[i] == 'X' || (i >= 1 && str[i - 1] == 'X') || (i >= 2 && str[i - 2] == 'X') || (i + 1 < len && str[i + 1] == 'X') || (i + 2 < len && str[i + 2] == 'X')) {
ans ^= SG(num);
num = 0;
}
else num++;
}
ans ^= SG(num);
return ans == 0;
}

void solve() {
way = 0;
len = strlen(str);
for (int i = 0; i < len; i++) {
if (str[i] != '.') continue;
str[i] = 'X';
if (judge() || GetRes())
res[way++] = i + 1;
str[i] = '.';
}
}

int main() {
memset(sg, -1, sizeof(sg));
scanf("%d", &t);
while (t--) {
scanf("%s", str);
solve();
if (way == 0) printf("LOSING\n\n");
else {
printf("WINNING\n%d", res[0]);
for (int i = 1; i < way; i++)
printf(" %d", res[i]);
printf("\n");
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: