hdu1729Stone Game

设当前的箱子容量为si,求出一个t满足:t + t * t < si,如果当前箱子里有ci颗石头,

1、ci > t 则必胜;

2、ci == t 则必败;

3、ci < t不能确定,将t作为si递归调用函数。

当满足ci > t时,return si - ci 作为当前状态的sg值。因为:

如图:hdu1729Stone Game_第1张图片
当ci在si点时,为有向图的端点,出度为0,也就是必败点,所以sg值为0;

当ci 位于si - 1时,ci的端点可能的sg值构成的集合为{0},所以当前sg值 为1;

当ci 位于si - 2 时,ci的端点可能的sg值构成的集合为{0, 1},所以当前的sg值为2;

#include 
#include 
#include 

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(){
  int n, c, s, cas = 0, flag;
    while(scanf("%d", &n), n){
        printf("Case %d:\n", ++cas);
        flag = 0;
        while(n--){
            scanf("%d%d", &s, &c);
            flag ^= sg(c, s);
        }
        if(flag)    printf("Yes\n");
        else    printf("No\n");
    }
    return 0;
}

你可能感兴趣的:(hdu,博弈)