1 条题解

  • 0
    @ 2025-8-24 21:25:39

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar Imakf
    **

    搬运于2025-08-24 21:25:38,当前版本为作者最后更新于2018-08-28 17:53:28,作者可能在搬运后再次修改,您可在原文处查看最新版

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

    以下是正文


    刷博弈论,看到这道题是红色的,我就来了

    结果一看???这真的是入门难度???恶意评分啊!

    首先

    读题!

    我读这道题目都花了好久,实际上意思就是把一个nn边形沿着对角线分割,分成n-2个三角形,在其中选中一个三角形成为黑三角形。然后JMcat , PZ两个人轮流拿走边上的一个三角形,谁能拿走黑三角形谁就赢了。

    做法

    本蒟蒻的做法就是分类讨论! 分3种情况——黑三角形和多少个三角形相邻。

    一、和11个三角形相邻

    显而易见,黑三角形本身露在外面,JMcat直接取走,puts("JMcat Win");

    二、和22个三角形相邻

    好像看不出什么……………………………………………………那就找规律

    规律如下表

    nn 白三角形数量 谁赢
    55 22 PZPZ
    66 33 JMcatJMcat
    77 44 PZPZ
    ...

    规律便一下出来了

    if(n%2==1)	puts("PZ Win");
    else puts("JMcat Win");
    

    证明

    JMcat的必败点就是如上图所示,每次拿走一个三角形实际上就是删去一个点,所以知道剩下5个点JMcat必败,因为一个人取一次,即可得出结论。

    三、和33个三角形相邻

    跟情况二一样,找规律

    nn 白三角形数量 谁赢
    66 33 JMcatJMcat
    77 44 PZPZ
    88 55 JMcatJMcat
    ...

    规律:

    if(n%2==1)	puts("PZ Win");
    else puts("JMcat Win");
    

    实际上这两种情况是一样的,就如上图,拿走一个三角形之后便变成了第二种情况。

    证明

    与情况二类似,不再赘述

    蒟蒻AC代码

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<map>
    struct tri{
        int a[3];
    }h[50000+5];
    bool point[50000+5];
    int main(){
        int n;
        scanf("%d",&n);
        for(int i=0;i<n-2;++i)
            for(int j=0;j<3;j++)
                scanf("%d",&h[i].a[j]);
        for(int j=0;j<3;++j)
            point[h[0].a[j]]=true;
        short ans=0;
        for(int i=1;i<n-2;++i){
            int _ans=0;
            for(int j=0;j<3;++j)
                _ans+=point[h[i].a[j]];
            if(_ans==2) ++ans;
        }
        if(ans==1)  puts("JMcat Win");
        else if(ans==2){
            if(n%2) puts("PZ Win");
            else puts("JMcat Win");
        }
        else{
            if(n%2) puts("PZ Win");
            else puts("JMcat Win");
        }
        return 0;
    }
    
    

    SOMEBODY:只要判断奇偶?

    他们的程序:

    #include<iostream>
    using namespace std;
    int main()
    {
        int n;
        cin>>n;
        if(n==5) //实质上是个打表
            cout<<"JMcat Win";
        else if(n%2==0)
                cout<<"JMcat Win"; 
                    else cout<<"PZ Win";
        return 0;
    }
    

    事实上这是个打表,没有任何意义,只是数据太水,合某些人胃口罢了。

    总结

    最后祝大家AK IOI

    • 1

    信息

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