1 条题解

  • 0
    @ 2025-8-24 22:46:58

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar Red0rangE
    .

    搬运于2025-08-24 22:46:58,当前版本为作者最后更新于2023-05-13 10:49:26,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    题意理解

    一道有趣而简单的博弈论题目。

    给出一个正整数 nn,接下来一行给出 nn 个正整数,表示这 nn 堆石子每堆石子的数量,两人可以不断从最左端有石子的一堆中拿石子到右边一堆,如果当前轮只剩下最后一堆石子,则这个人输。

    思路阐述

    将最后一堆留给对手,即将倒数第二堆的主动权在自己手中,想要倒数第二堆的主动权,让倒数第三堆必须被对手挪完,即倒数第三堆只剩下一个石子,从后往前推,直至第一个,所以除非第一堆只有一个石子,否则主动权将永远在先手手中,即先手胜利。

    但是注意 n=2n=2 的情况,此时策略不同,先手不管第一堆有多少个,直接全部放到下一堆即可。

    策略:当 n=2n=2 时,先手直接把第一堆挪完,这样就只剩下一堆了;当 n>2n>2 时,重复将当前堆只剩下一个石子,以实现当 n=2n=2 时移动权在手中。

    举个例子:

    3 8 1 1 6 先手轮\text{3 8 1 1 6 先手轮} 1 10 1 1 6 后手轮\text{1 10 1 1 6 后手轮} 0 11 1 1 6 先手轮\text{0 11 1 1 6 先手轮} 0 1 11 1 6 后手轮\text{0 1 11 1 6 后手轮} 0 0 12 1 6 先手轮\text{0 0 12 1 6 先手轮} 0 0 1 12 6 后手轮\text{0 0 1 12 6 后手轮} 0 0 0 13 6 先手轮\text{0 0 0 13 6 先手轮} 0 0 0 0 19 后手轮\text{0 0 0 0 19 后手轮}

    综上得出:当 n=2n=2 时,先手必胜;当 n>2n>2 时,如果第一个数 v1v\ne 1,先手必胜,否则后手必胜。

    代码呈现

    #include <bits/stdc++.h>
    using namespace std;
    
    int n,v;
    
    signed main(){
        
        scanf("%d",&n);
        scanf("%d",&v);//只需要第一堆的数量就可以判断了
        if (n==2){//只有两堆,特判先手必胜
            printf("Charlie");
            return 0;
        }
        if (v==1) printf("Dan");//第一堆只有一个
        else printf("Charlie");
        return 0;
        
    }
    
    

    希望可以帮到各位大佬。

    • 1

    信息

    ID
    8652
    时间
    1000ms
    内存
    512MiB
    难度
    3
    标签
    递交数
    0
    已通过
    0
    上传者