hdu1729 Stone Game sg

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

  
  
Case 1: Yes Case 2: No


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");
    }
}


 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值