HDU2486_A simple stone game

时间:2020-12-09 14:53:17

这个题目是这样的,一堆石子有n个,首先第一个人开始可以去1-(n-1)个,接下来两人轮流取石子,每个人可取的石子数必须是一个不超过上一次被取的石子的K倍的整数。

现在求对于一堆数量为n的石子是否为必胜态,如果是的话,先手者第一次最少可以取多少石子?

这个题目是一个典型的K倍动态减法游戏。构造两个数列,然后直接判断就好了。

至于数列的构造原理,我自己弄得也不是很透彻,等我透彻了再写写吧。

对于输出最小的可行解,就是逐步减小并且判断就好了。

 #include <iostream>
#include <cstdio>
#define maxn 5000000
using namespace std; int a[maxn],b[maxn],k,n,i,j,ans; int main()
{
int t,cas=;
scanf("%d",&t);
while (t--)
{
scanf("%d%d",&n,&k);
a[]=b[]=;
i=j=;
for (; a[i]<n; i++)//构造序列
{
a[i+]=b[i]+;
while (a[j+]*k<a[i+]) j++;
if (a[j]*k<a[i+]) b[i+]=b[j]+a[i+];
else b[i+]=a[i+];
}
printf("Case %d: ",++cas);
if (n==a[i]) printf("lose\n");
else
{
for (; n; i--)
if (n>=a[i]) n-=a[i],ans=a[i];
printf("%d\n",ans);
}
}
return ;
}