Number Cutting Game HDU - 2848(博弈论+搜索)

题意:给一个数字n,和段数k,要求一个人把n分成k段,然后k段数字相加。如果第一个人能分成k段,则第二个人分割,第二个人能分割成k段,则第一个人继续。。。直到一方不能分割成k段时 lose。

解析见代码注释

AC代码

#include<cstdio>
#include<cstring>
using namespace std;
typedef long long LL;
const int N=1e9;
const int inf=0x3f3f3f3f;
const double eps=1e-7;
#define ls (i<<1)
#define rs (i<<1|1)
LL n,m;
LL base[25];
bool dfs(LL sum,LL left,LL step)
{
///m是段数,m-1是切割次数
    if(step==m-1) ///第一个切割完了,轮到第二个人,若第二个人赢了,那么第一个人输
    {
        if(dfs(0,sum+left,0)) return 0;///另一个人开始游戏,sum+left是第二个人开始时未分割的数字
        return 1;
    }
    for(int i=1;base[i]<=left;i++) ///切割不了,便不会进入循环,即return 0;
    {
        if(dfs(sum+left%base[i],left/base[i],step+1) ) ///枚举所有切割,有一种切割能保证胜利return 1
            return 1;
    }
    return 0; //游戏以一方不能切割成m段而结束
}
int main()
{
    base[0]=1;
    for(int i=1;i<=20;i++) base[i]=10*base[i-1];//预处理
    while(scanf("%lld%lld",&n,&m)!=EOF)
    {
        printf("%d\n",dfs(0,n,0) );
    }
}
posted @ 2019-12-11 21:15  DeepJay  阅读(111)  评论(0编辑  收藏  举报