Stone Game
Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 1877 Accepted Submission(s): 495
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
Source
“网新恩普杯”杭州电子科技大学程序设计邀请赛
Recommend
lcy
还没有完全理解这题。可以参考这http://qianmacao.blog.163.com/blog/static/2033971802012343334856/
题意是给n个盒子,并给si,ci,即一个盒子里原本有ci个石子,最多装si个石子,每次可以往盒子里装少于或者等于盒子里石子的平方个石子,问先手是否有必胜策略。
我们找一个p,p满足p*p+p<s。
一、当ci>p的时候,肯定能一次到达装满的状态,所以是必胜态。返回的sg值是si-ci,我们知道最终的状态是盒子装满的状态,即(si,si),这点的sg值为0,那么(si,si-1)只能到达(si,si),那么这点的sg值为1,依次类推为2,3,……,所以到(si,ci)的时候,sg值也就为si-ci.
二、当ci==p的时候,到这个状态的人一次肯定装不满盒子,不管他采取什么策略,下一个人一定可以装满盒子,所以这是必败态。
三、当ci<p的时候,这个情况输赢情况不一定,把si当作p,继续调用求sg值的函数,这一点我很费解,暂时不理解。路过的人若明白了,可以帮我解答一下,万分感谢!~
貌似是因为p这个点是必败点,而si这个点也是必败点,所以我们只需要用p代替s就可以了。
#include<iostream>
#include<cstdlib>
#include<stdio.h>
#include<math.h>
using namespace std;
int find(int s,int c)
{
int p=sqrt(s+0.0);
while(p+p*p>=s) p--;
if(c>p) return s-c;
else return find(p,c);
}
int main()
{
int count=1;
int n;
while(scanf("%d",&n)&&n)
{
int ans=0;
int s,c;
while(n--)
{
scanf("%d%d",&s,&c);
ans^=find(s,c);
}
printf("Case %d:\n",count++);
if(ans) puts("Yes");
else puts("No");
}
}