题意:
给出一个串,由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[N], way, len, sg[N];
char str[N];
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[N];
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;
}