zoukankan      html  css  js  c++  java
  • hdu 1729 Stone Game

    Stone Game

     HDU - 1729 

    题意:
    给定n个箱子,每个箱子的容量为si,每个箱子里最初有ci个石子,每次放入石子不能超过放入前的石子数的平方,谁无法继续放入石子就算输。
     
    /*
        这是个SG函数的基础题?并不是的吧。。
        求一个t使t+t*t=si,那么
        1.当ci>t时,是必胜态,可以一次性放满箱子,即(si,si)。
        2.当ci==t时,即便只放一个,下一个状态t+1+(t+1)*(t+1)一定能放满箱子必胜,所以ci==t这个状态必败。
        3.当ci=si-t,同样的方法判断必胜必败,这样就可以通过递归求解sg值。
         
        求sg:要得到sg需要对他的子集做mex{}运算,求出不属于该集合的最小非负整数。
        在ci>t时满足
        对于ci==si这个点,ci在有向图中没有出度(必败),因此返回si-ci=0,;
        在ci==si-1时,它能到达的只有si点,sg[ci]={sg[si]=0},所以sg[ci]=1.
        在ci==si-2时,他能到达的点有si-1,si,所以sg[ci]={sg[si-1]=1,sg[si]=0},所以sg[ci]=2.
        因此在ci>t时返回si-ci
        在ci==t是是必败,可直接返回0,也可以不做判断直接进入下一轮递归。
    */
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #define maxn 51
    using namespace std;
    int n;
    int getSG(int s,int c){
        int t=sqrt(s);
        while(t*t+t>=s)t--;
        if(c>t)return s-c;
        if(c==t)return 0;
        return getSG(t,c);
    }
    int main(){
        int cas=0;
        while(scanf("%d",&n)){
            cas++;
            if(n==0)return 0;
            printf("Case %d:
    ",cas);
            int ans=0,s,c;
            for(int i=1;i<=n;i++){
                scanf("%d%d",&s,&c);
                ans^=getSG(s,c);
            }
            if(ans)puts("Yes");
            else puts("No");
        }
    }
  • 相关阅读:
    验证码
    九九乘法表
    P121 6.7 第一题和第二题
    二分搜索法(转载自vanezkw)
    用for循环打印菱形
    用while循环语句计算1!+2!+……20!之和
    数的阶乘之和
    9.29
    doGet与doPost的区别
    JavaScript习题
  • 原文地址:https://www.cnblogs.com/thmyl/p/8137585.html
Copyright © 2011-2022 走看看