LUCKY BOY 博弈+剪枝

G

Time Limit:1000MS  Memory Limit:65536K
Total Submit:64 Accepted:20

Description

Recently, Lur have a good luck. He is also the cleverest boy in his school as he create the most popular computer game ? Lucky Boy. The game is played by two players, a and b, in 2d planar .In the game Lucky Boy, there are n different points on plane, each time one can remove one or multiple co-line points from the plane. The one who can firstly remove more than two points from the plane wins. The one who removes the last point on the plane can also win the game. You may assume that two players are both clever enough that they can always make the best choice. The winner is called Lucky Boy.
Given the n points, can you tell me who will be the Lucky Boy ? Note that player a will always the first one to remove points from the plane. 

Input

The first line of each case is an integer n,following n lines each contains two integers x ans y(0~1e8),describing the place of each point.

Output

Output “a is the lucky boy.” in a single line if a win the game, otherwise you should output “b is the lucky boy.” in a single line.


Sample Input

3

0 0

1 1

2 2

3

0 0

1 1

2 3

 
 

Sample Output

a is the lucky boy.

b is the lucky boy.

 
 

题目大意:

在一个平面上有n个旗子,2个人轮流取棋子,一次可以拿一个或者是连成直线的多个,如果有人一次拿了2个以上或者拿了最后一个则为获胜,2人都取最优策略,问先手能否赢。

思路:

首先如果初始平面有3个点连成一线的则毫无疑问先手获胜,否则,若先手想获胜,最后一步留给自己的应该是1个或者2个,因此最后倒数第二步需要给对手留下3个,于是倒数第三步需要给对手留下6个....倒数第n步需要给对手留下3n个,即第一步拿了以后需要给对手留下3n个,也就是判断是否为3个倍数即可,若不是3的倍数则第一次取完后可给后手留下3的倍数个,若开始有3n个,则先手取了以后后手可给先手留下3n个,先手就输了。

技巧:

如果数据过大,每次需要对n个点进行o(n^3)次计算太费时间,可以先判断点数能否被3整除,若不能被3整除则无需计算是否有共线,因为如果有共线则第一步就赢,如果没有也可以通过每次给对手留下3n个的策略来获胜。

0msAC代码:

#include<cstdio>
struct Point
{
	int x;
	int y;
}p[1010];
int main()
{
	int n,x,y;
	while (scanf("%d", &n) != EOF)
	{
		for (int i = 1; i <= n;i++) scanf("%d%d", &p[i].x, &p[i].y);
		bool win = false;
		if (n % 3)win = true;
		else
		{
			for (int i = 1; i <= n&&!win; i++)
				for (int j = i+1; j <= n&&!win; j++)
					for (int k = j+1; k <= n&&!win; k++)
						if ((p[i].x - p[j].x)*(p[i].y - p[k].y) == (p[i].x - p[k].x)*(p[i].y - p[j].y))
							win = true;
		}
		if (win)printf("a is the lucky boy.\n");
		else printf("b is the lucky boy.\n");
	}
	return 0;
}


你可能感兴趣的:(博弈,剪枝)