HDU1729Stone Game

Problem Description
This game is a two-player game and is played as follows:

1. There are n boxes; each box has its size. The box can hold up to s stones if the size is s.
2. At the beginning of the game, there are some stones in these boxes.
3. The players take turns choosing a box and put a number of stones into the box. The number mustn’t be great than the square of the number of stones before the player adds the stones. For example, the player can add 1 to 9 stones if there are 3 stones in the box. Of course, the total number of stones mustn’t be great than the size of the box.
4.Who can’t add stones any more will loss the game.

Give an Initial state of the game. You are supposed to find whether the first player will win the game if both of the players make the best strategy.
 

Input
The input file contains several test cases.
Each test case begins with an integer N, 0 < N ≤ 50, the number of the boxes.
In the next N line there are two integer si, ci (0 ≤ ci ≤ si ≤ 1,000,000) on each line, as the size of the box is si and there are ci stones in the box.
N = 0 indicates the end of input and should not be processed.
 

Output
For each test case, output the number of the case on the first line, then output “Yes” (without quotes) on the next line if the first player can win the game, otherwise output “No”.
 

Sample Input

3 2 0 3 3 6 2 2 6 3 6 3 0
 

Sample Output

Case 1: Yes Case 2: No

 

题意:你有一些盒子,这些盒子有一个体积si,然后你和另一个人往里面放石子,盒子里面本来有一些石子,你和另外一个人轮流放的时候放的最多不能超过里面的石子的平方(比如里面原来有3个,那么你可以放的石子数量是1-9)当然了石子总数量不能超过其体积,最后不能放石子的输。

分析:找必败态:
设t,t*t +t < s 而且使 t 尽量的大,则(t+1)*(t+1) +(t+1) >= s,
因此
1. c > t 则当前状态是必胜态,因为c*c+c >= s成立
2. c == t 则当前状态为必败态,因为最多放c*c个石头,
瓶子未满,对手必胜,至少放1个石头,则对手也是必胜。
3. c < t 当前状态无法确定,而在瓶子中已经有c个石头的前提下,
容量为 s 和容量为 t 的状态是等价的,如果(t, c)是必败态,则(s, c)也是必败态。

#include "stdio.h"
#include "math.h"
int getsg(int s,int c)
{
	int t=sqrt(s);
	while (t*t+t>=s)
		t--;
	if(c>t)
		return s-c;
	else if(c==t)
		return 0;
	else
		return getsg(t,c);
}
int main()
{
	int n,s,c,i,j;
	int kk=0;
	while (scanf("%d",&n)==1&&(n))
	{
		int mark=0;
		while(n--)		
		{
			scanf("%d%d",&s,&c);
			mark^=getsg(s,c);
		}
		if(mark)
			printf("Case %d:\nYes\n",++kk);
		else 
			printf("Case %d:\nNo\n",++kk);
	}
} 



你可能感兴趣的:(博弈分析题)