题意:给一个数字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
",dfs(0,n,0) );
}
}