洛谷 2953 博弈论 解题报告

题目如下

贝茜和约翰在玩一个数字游戏.贝茜需要你帮助她.

游戏一共进行了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;
}

思路很简单,一道简单的博弈题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值