题目如下
贝茜和约翰在玩一个数字游戏.贝茜需要你帮助她.
游戏一共进行了G(1≤G≤100)场.第i场游戏开始于一个正整数Ni(l≤Ni≤1,000,000).游
戏规则是这样的:双方轮流操作,将当前的数字减去一个数,这个数可以是当前数字的最大数码,也可以是最小的非0数码.比如当前的数是3014,操作者可以减去1变成3013,也可以减去4变成3010.若干次操作之后,这个数字会变成0.这时候不能再操作的一方为输家. 贝茜总是先开始操作.如果贝茜和约翰都足够聪明,执行最好的策略.请你计算最后的赢家.
比如,一场游戏开始于13.贝茜将13减去3变成10.约翰只能将10减去1变成9.贝茜再将9减去9变成0.最后贝茜赢.
刚开始看这个题没看到最大数码这个条件,推了一下直接就10的倍数是输 否则赢的代码就提交了
结果只得了40分,之后看到了条件就重新写了一下。
主要思路(博弈核心):
必胜态可以转移到至少一个必败态
必败态只能转移到必胜态
只要找到最小数码和最大数码往前推就行了
AC代码如下
#include <stdio.h>
#include <stdlib.h>
int skr[1000001];
int main()
{
int n,tmp=0,min=10,max=-1;
for(int i=1;i<=9;i++)
skr[i]=1;
int flag=10;
for(;flag<=1000000;flag++)
{
min=10;
max=-1;
tmp=flag;
while(tmp)
{
int z=tmp%10;
tmp/=10;
if(z>0&&min>z) min=z;
if(z>0&&max<z) max=z;
}//找到最大和最小数码
if(skr[flag-min]==0||skr[flag-max]==0)
skr[flag]=1;//只要能转移到必败态就将当前状态变为必胜态,否则不变
}
scanf("%d",&n);
int p=0;
for(int i=0;i<n;i++)
{
scanf("%d",&p);
if(skr[p]) printf("YES\n");
else printf("NO\n");
}
return 0;
}
思路很简单,一道简单的博弈题