sg函数 hdu 1729 Stone Game

  • Post author:
  • Post category:其他



题目大意:(取石子游戏)有n个箱子,体积为Si,当前箱子里的石子数为Ci。两个人轮流往箱子里放石子,而且每一次放是数量都有限制,不能超过当前箱子内石子数的平方。例如箱子里有3颗石子,那么下一个人就可以放1~9颗石子,直到箱子被装满。当有一方放不下石子时游戏结束,最后放不下石子的人输。







首先空间为20的时候,


ci == 20 sg = 0;






ci == 19 sg = 1;




ci == 18 sg = 2;




ci == 17 sg = 3;



…………………




直到 ci = 4 的时候  sg = 16; 显然此时可以放4 * 4 + 4 == 16个还是赢,


所以


在 4 ~ 20 范围内  sg(ci,si) = si – ci;




但是当 ci == 3 的时候 sg == 0,之后又是一个循环,所以求sg是个递归的过程;




对于任意一个si,都要找到一个临界点,这个临界点 t 显然得满足   t*t == si – t ;   t–;




在临界点右边

sg(ci,si) = si – ci;





临界点左边

sg(ci,t);


#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;

int sg( int c, int s){
    int t = sqrt(s);    
    while(t*t + t >= s)    t--;
    if(c > t)    return s - c;
    else    return sg(c, t);
}
int main(){
    for (int kase(1),n;scanf("%d",&n) && n && printf("Case %d:\n",kase++);){
        int si,ci,ans(0);
        while(n--){
            scanf("%d%d",&si,&ci);
            ans ^= sg(ci,si);
        }
        printf( ans ? "Yes\n" : "No\n");
    }
    return 0;
}



版权声明:本文为betwater原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。