uva10561(SG函數)



Problem C
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


思路和題意大白書上已經說得很清楚了,渣渣只是用代碼實現了,好弱的感覺啊

#include<stdio.h>
#include<cstring>
#include<iostream>
#include<vector>
#include<cmath>
#include<set>
#include<utility>
#include<string>
#include<queue>
#include<algorithm>
#include<functional>
#define LL long long
#define MOD 1000000007
#define MM 1000010
#define Inf (1<<30)
using namespace std;
char s[210];
bool vis[210];
int g[210];
int sg(int x)
{
	memset(vis,0,sizeof(vis));
	for (int i = x - 3, j = -2; i >= 0; i--, j++)
		vis[g[max(j, 0)] ^ g[i]] = 1;
	for (int i = 0; i < 210;i++)
	if (!vis[i])return i;
}
int judge()
{
	int L = strlen(s + 1);
	int res[210], cnt = 0;
	for (int i = 1; i <= L; i++)
	{
		if (i + 1 <= L&&s[i] == 'X'&&s[i + 1] == 'X')
		{
			if (i - 1 >= 1)res[cnt++] = i - 1;
			if (i + 2 <= L)res[cnt++] = i + 2;
		}
		if (i + 2 <= L&&s[i] == 'X'&&s[i + 2] == 'X')res[cnt++] = i + 1;
	}
	if (cnt > 0)
	{
		puts("WINNING");
		for (int i = 0; i < cnt; i++)
			printf(i == cnt - 1 ? "%d\n" : "%d ", res[i]);
		return 1;
	}
	return 0;
}
bool check(int x)
{
	int L = strlen(s + 1);
	int dx[] = { -2, -1, 0, 1, 2 };
	for (int j = 0; j < 5; j++)
	{
		int xx = x + dx[j];
		if (xx < 1 || xx > L)continue;
		if (s[xx] == 'X')return false;
	}
	return true;
}
int calc()
{
	int ans = 0, cnt = 0;
	int L = strlen(s + 1);
	for (int i = 1; i <= L; i++)
	{
		if (!check(i))ans ^= g[cnt], cnt = 0;
		else cnt++;
	}
	return ans^g[cnt];
}
int main()
{
	int T;
	g[0] = 0;
	g[1] = g[2] = g[3] = 1;
	for (int i = 4; i <= 205; i++)
		g[i] = sg(i);
	scanf("%d", &T);
	while (T--)
	{
		scanf("%s", s + 1);
		if (judge())continue;
		int ans = calc();
		if (ans == 0)puts("LOSING\n");
		else
		{
			int res[210];
			int L = strlen(s + 1), cnt = 0;
			puts("WINNING");
			for (int i = 1; i <= L; i++)
			{
				if (!check(i))continue;
				s[i] = 'X';
				if (calc() == 0)res[cnt++] = i;
				s[i] = '.';
			}
			for (int i = 0; i < cnt; i++)
				printf(i == cnt - 1 ? "%d\n" : "%d ", res[i]);
		}
	}
	return 0;
}


發佈了123 篇原創文章 · 獲贊 14 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章