HDU 4203

本文探讨了SG(Sprague-Grundy)函数在不同参数k下的博弈策略,通过编写打表程序发现k为奇数时的简单规律及k为偶数时的循环特性,并给出了一种高效的AC程序实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

sg博弈

首先写个SG打表程序

#include<cstdio>
#include<stdlib.h>
#include<cstring>
#include<queue>
using namespace std;
int sg[110],k;
int find(int i){
    if(sg[i]!=-1)return sg[i];
    int use[100],j;
    memset(use,0,sizeof(use));
    for(j=1;j<=i;j*=k)
        use[find(i-j)]=1;
    j=0;
    while(use[j])j++;
    return sg[i]=j;
}
int main(){
    int n,i;
    scanf("%d",&k);
    memset(sg,-1,sizeof(sg));
    for(i=1;i<=100;i++){
        printf("%d %d\n",i,find(i));
    }
}

然后可以发现规律,当k为奇数时,1,0,1,0,1,0。。。。这样变化,故n为奇数只需移走1个石头,而n为偶数必败

当k为偶数时,SG表是一个k+1的循环,比如k=4时,1,0,1,2,0,1,0,1,2,0.。。。故分析可知sg值为0的必败,sg值为1的只需要移走1个石头,sg值为2时,如果移走一个,则走到sg为1的点上还是必败,而移动k个石子易知可到达必胜态

AC程序

#include<cstdio>
#include<stdlib.h>
#include<cstring>
#include<queue>
using namespace std;

int main(){
    int i,t,T,k,s;
    scanf("%d",&T);
    for(t=1;t<=T;t++){
        scanf("%d %d",&s,&k);
        if(k&1){
            if(s&1)printf("1\n");
            else printf("0\n");
        }
        else{
            int tem=s%(k+1);
            if(tem==k)printf("%d\n",k);
            else{
                if(tem&1)printf("1\n");
                else printf("0\n");
            }
        }
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值