zoukankan      html  css  js  c++  java
  • [SDOI2010]猪国杀

    题目描述

    《猪国杀》是一种多猪牌类回合制游戏,一共有三种角色:主猪,忠猪,反猪。每局游戏主猪有且只有一只,忠猪和反猪可以有多只,每只猪扮演一种角色。

    游戏目的:

    主猪(MP):自己存活的情况下消灭所有的反猪。

    忠猪(ZP):不惜一切保护主猪,胜利条件与主猪相同。

    反猪(AP):杀死主猪。

    游戏过程:

    游戏开始时候,每个玩家手里都会有4张牌,且体力上限和初始体力都是4。

    开始游戏时,从主猪开始,按照逆时针方向(数据中就是按照编号从1,2,3..n,1..的顺序)依次行动。

    每个玩家自己的回合可以分为4个阶段:

    ◎摸牌阶段:从牌堆顶部摸两张牌,依次放到手牌的最右边;

    ◎出牌阶段:你可以使用0张到任意张牌,每次使用牌的时候都使用最靠左的能够使用的牌。当然,要满足如下规则:

    1.如果没有猪哥连弩,每个出牌阶段只能使用一次“杀”来攻击;

    2.任何牌被使用后被弃置(武器是装备上);

    被弃置的牌以后都不能再用,即与游戏无关;

    各种牌介绍:

    每张手牌用一个字母表示,字母代表牌的种类。

    ◎基本牌:

    『桃(P)』:在自己的回合内,如果自己的体力值不等于体力上限,那么使用一个桃可以为自己补充一点体力,否则不能使用桃;桃只能对自己使用;在自己的回合外,如果自己的血变为0或者更低,那么也可以使用;

    『杀(K)』:在自己的回合内,对攻击范围内除自己以外的一名角色使用。如果没有被『闪』抵消,则造成1点伤害。无论有无武器,杀的攻击范围都是1;

    『闪(D)』:当你受到杀的攻击时,可以弃置一张闪来抵消杀的效果;

    ◎锦囊牌:

    『决斗(F)』:出牌阶段,对除自己以外任意一名角色使用,由目标角色先开始,自己和目标角色轮流弃置一张杀,首先没有杀可弃的一方受到1点伤害,另一方视为此伤害的来源;

    『南猪入侵(N)』:出牌阶段,对除你以外所有角色使用,按逆时针顺序从使用者下家开始依次结算,除非弃置一张杀,否则受到1点伤害;

    『万箭齐发(W)』:和南猪入侵类似,不过要弃置的不是杀而是闪;

    『无懈可击(J)』:在目标锦囊生效前抵消其效果。每次有一张锦囊即将生效时,从使用这张锦囊的猪开始,按照逆时针顺序,依次得到使用无懈可击的机会;

    效果:用于决斗时,决斗无效并弃置;用于南猪入侵或万箭齐发时,当结算到某个角色时才能使用,当前角色不需弃置牌并且不会受到伤害(仅对一个角色产生效果);用于无懈可击时,成为目标的无懈可击被无效。

    ◎装备牌:

    『猪哥连弩(Z)』:武器,攻击范围1,出牌阶段你可以使用任意张杀;

    同一时刻最多只能装一个武器;如果先前已经有了一把武器,那么之后再装武器的话,会弃置以前的武器来装现在的武器;

    特殊事件及概念解释:

    ◎伤害来源:杀、南猪入侵、万箭齐发的伤害来源均是使用该牌的猪,决斗的伤害来源如上;

    ◎距离:两只猪的距离定义为沿着逆时针方向间隔的猪数+1。即初始时1和2的距离为1,但是2和1的距离就是n-1。注意一个角色的死亡会导致一些猪距离的改变;

    ◎玩家死亡:如果该玩家的体力降到0或者更低,并且自己手中没有足够的桃使得自己的体力值回到1,那么就死亡了,死亡后所有的牌(装备区,手牌区)被弃置;

    ◎奖励与惩罚:反猪死亡时,最后一个伤害来源处(即使是反猪)立即摸三张牌。忠猪死亡时,如果最后一个伤害来源是主猪,那么主猪所有装备牌、手牌被弃置;

    ◎注意,一旦达成胜利条件,游戏立刻结束,因此即使会摸3张牌或者还有牌可以用也不用执行了。

    几种行为:

    ◎献殷勤:使用无懈可击挡下南猪入侵、万箭齐发、决斗;使用无懈可击抵消表敌意;

    ◎表敌意:对某个角色使用杀、决斗;使用无懈可击抵消献殷勤;

    ◎跳忠:即通过行动表示自己是忠猪。跳忠行动就是对主猪或对某只已经跳忠的猪献殷勤,或者对某只已经跳反的猪表敌意;

    ◎跳反:即通过行动表示自己是反猪。跳反行动就是对主猪或对某只已经跳忠的猪表敌意,或者对某只已经跳反的猪献殷勤;

    忠猪不会跳反,反猪也不会跳忠;不管是忠猪还是反猪,能够跳必然跳;

    行动准则:

    共性:每个角色如果手里有桃且生命值未满,那么必然吃掉;有南猪入侵、万箭齐发、必然使用;有装备必然装上;受到杀时,有闪必然弃置;响应南猪入侵或者万箭齐发时候,有杀/闪必然弃置;不会对未表明身份的猪献殷勤(包括自己);

    特性:

    ◎主猪:主猪会认为没有跳身份,且用南猪入侵/万箭齐发对自己造成伤害的猪是“类反猪”(没伤害到不算,注意“类反猪”并没有表明身份),如果之后 跳了,那么主猪会重新认识这只猪;对于每种表敌意的方式,对逆时针方向能够执行到的第一只“类反猪”或者已跳反猪表;如果没有,那么就不表敌意;决斗时会 不遗余力弃置杀;如果能对已经跳忠的猪或自己献殷勤,那么一定献;如果能够对已经跳反的猪表敌意,那么一定表;

    ◎忠猪:对于每种表敌意的方式,对逆时针方向能够执行到的第一只已经跳反的猪表,如果没有,那么就不表敌意;决斗时,如果对方是主猪,那么不会弃置杀,否则,会不遗余力弃置杀;如果有机会对主猪或者已经跳忠的猪献殷勤,那么一定献;

    ◎反猪:对于每种表敌意的方式,如果有机会则对主猪表,否则,对逆时针方向能够执行到的第一只已经跳忠的猪表,如果没有,那么就不表敌意;决斗时会不遗余力弃置杀;如果有机会对已经跳反的猪献殷勤,那么一定献;

    限于iPig只会用P++语言写A + B,他请你用Pigcal(Pascal)、P(C)或P++(C++)语言来帮他预测最后的结果。

    终于手切SDOI神题猪国杀发博客纪念。

    一些问题:

    1.献殷勤(表敌意)==跳身份,只要跳身份就是亮身份。

    2.使用无懈可击==亮身份。

    3.濒死时的桃要加血!!!

    hack点:

    若主对类反猪出决斗,类反猪出杀算不算表敌意?

    (然而数据并没有卡,可能是因为题目描述。)

    然后是oi中罕见的400+代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int n,m,crd_num=1;
    char crd[2050],tmp[5];
    int mem;
    bool lei_fan_zhu[15],tiao[15];
    struct Pig
    {
        int shenfen,shili,l,r;
        char shoupai[5050];
        bool use[5050];
        int gg;
        int bhit,hit;
        bool nu;
        void ins(char ch)
        {
            r++;
            if(r>5000)r=1;
            shoupai[r]=ch,use[r]=1;
        }
        bool push_K()
        {
            for(int i=l;i!=r%5000+1;i=(i==5000)?1:i+1)
            {
                if(!use[i])continue;
                if(shoupai[i]=='K')
                {
                    use[i]=0;
                    return 1;
                }
            }
            return 0;
        }
        bool push_D()
        {
            for(int i=l;i!=r%5000+1;i=(i==5000)?1:i+1)
            {
                if(!use[i])continue;
                if(shoupai[i]=='D')
                {
                    use[i]=0;
                    return 1;
                }
            }
            return 0;
        }
        bool push_P()
        {
            for(int i=l;i!=r%5000+1;i=(i==5000)?1:i+1)
            {
                if(!use[i])continue;
                if(shoupai[i]=='P')
                {
                    use[i]=0;
                    gg++;
                    return 1;
                }
            }
            return 0;
        }
    }p[15];
    bool push_J(int x)
    {
        for(int i=p[x].l;i!=p[x].r%5000+1;i=(i==5000)?1:i+1)
        {
            if(!p[x].use[i])continue;
            if(p[x].shoupai[i]!='J')continue;
            tiao[x]=1;
            lei_fan_zhu[x]=0;
            p[x].use[i]=0;
            bool fan_zhi = 0;
            for(int j=x%n+1;j!=x;j=(j==n)?1:j+1)
            {
                if(p[x].shili!=p[j].shili)
                {
                    if(push_J(j))
                    {
                        fan_zhi=1;
                        break;
                    }
                }
            }
            if(!fan_zhi)return 1;
        }
        return 0;
    }
    void print()
    {
        if(p[1].gg<=0)
        {
            printf("FP
    ");
        }else
        {
            printf("MP
    ");
        }
        for(int i=1;i<=n;i++)
        {
            if(p[i].gg<=0)
            {
                printf("DEAD
    ");
            }else
            {
                for(int j=p[i].l;j!=p[i].r%5000+1;j=(j==5000)?1:j+1)
                {
                    if(p[i].use[j])printf("%c ",p[i].shoupai[j]);
                }
                printf("
    ");
            }
        }
        exit(0);
    }
    void dead(int i,int to)
    {
        p[p[to].bhit].hit=p[to].hit;
        p[p[to].hit].bhit=p[to].bhit;
        memset(p[to].use,0,sizeof(p[to].use));
        if(to==1)
        {
            print();
        }
        if(p[to].shenfen==3)
        {
            mem--;
            if(!mem)print();
            p[i].ins(crd[crd_num]),p[i].ins(crd[crd_num+1]),p[i].ins(crd[crd_num+2]);
            crd_num+=3;if(crd_num>m)crd_num=m;
        }
        if(i==1&&p[to].shenfen==2)
        {
            p[1].nu=0;
            memset(p[1].use,0,sizeof(p[1].use));
            p[1].l=1,p[1].r=1;
        }
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            scanf("%s",tmp+1);
            if(tmp[1]=='M')p[i].shenfen=1,p[i].shili=1;
            else if(tmp[1]=='Z')p[i].shenfen=2,p[i].shili=1;
            else p[i].shenfen=3,mem++,p[i].shili=2;
            p[i].l=1,p[i].r=4,p[i].gg=4,p[i].bhit=i-1+(i==1)*n,p[i].hit=i%n+1;
            for(int j=1;j<=4;j++)
            {
                scanf("%s",tmp+1);
                p[i].shoupai[j]=tmp[1];
                p[i].use[j]=1;
            }
        }
        tiao[1]=1;
        for(int i=1;i<=m;i++)
        {
            scanf("%s",tmp+1);
            crd[i]=tmp[1];
        }
        crd[m+1]=crd[m+2]=crd[m+3]=crd[m];
        while(mem&&p[1].gg>0)
        {
            bool push_Kill=0;
            for(int i=1;i<=n;i++)
            {
                if(p[i].gg<=0)continue;
                push_Kill=0;
                while(p[i].use[p[i].l]==0&&p[i].l!=p[i].r)p[i].l=(p[i].l==5000)?1:p[i].l+1;
                while(p[i].use[p[i].r]==0&&p[i].l!=p[i].r)p[i].r=(p[i].r==1)?5000:p[i].r-1;
                p[i].ins(crd[crd_num]),p[i].ins(crd[crd_num+1]);
                crd_num+=2;if(crd_num>m)crd_num=m;
                for(int j=p[i].l;j!=p[i].r%5000+1;j=(j==5000)?1:j+1)
                {
                    if(!p[i].use[j])continue;
                    if(p[i].shoupai[j]=='J'||p[i].shoupai[j]=='D')continue;
                    if(p[i].shoupai[j]=='Z')
                    {
                        p[i].use[j]=0;
                        p[i].nu=1;
                        j=p[i].l-1;
                    }else if(p[i].shoupai[j]=='N')
                    {
                        p[i].use[j]=0;
                        for(int to=i%n+1;to!=i;to=(to==n)?1:to+1)
                        {
                            if(p[to].gg<=0)continue;
                            if(tiao[to])
                            {
                                bool safe=0,kkk=0;
                                for(int sec=i;(sec!=i)||(kkk==0);sec=(sec==n)?1:sec+1)
                                {
                                    if(p[sec].gg<=0)continue;
                                    kkk=1;
                                    if(p[sec].shili==p[to].shili)
                                    {
                                        if(push_J(sec))
                                        {
                                            safe=1;
                                            break;
                                        }
                                    }
                                }
                                if(safe)continue;
                            }
                            if(!p[to].push_K())
                            {
                                p[to].gg--;
                                if(to==1&&!tiao[i])
                                    lei_fan_zhu[i]=1;
                                if(p[to].gg<=0)
                                {
                                    if(!p[to].push_P())dead(i,to);
                                }
                            }
                        }
                        j=p[i].l-1;
                    }else if(p[i].shoupai[j]=='W')
                    {
                        p[i].use[j]=0;
                        for(int to=i%n+1;to!=i;to=(to==n)?1:to+1)
                        {
                            if(p[to].gg<=0)continue;
                            if(tiao[to])
                            {
                                bool safe=0,kkk=0;
                                for(int sec=i;(sec!=i)||(kkk==0);sec=(sec==n)?1:sec+1)
                                {
                                    kkk=1;
                                    if(p[sec].shili==p[to].shili)
                                    {
                                        if(push_J(sec))
                                        {
                                            safe=1;
                                            break;
                                        }
                                    }
                                }
                                if(safe)continue;
                            }
                            if(!p[to].push_D())
                            {
                                p[to].gg--;
                                if(to==1&&!tiao[i])
                                    lei_fan_zhu[i]=1;
                                if(p[to].gg<=0)
                                {
                                    if(!p[to].push_P())dead(i,to);
                                    
                                }
                            }
                        }
                        j=p[i].l-1;
                    }else if(p[i].shoupai[j]=='P')
                    {
                        if(p[i].gg!=4)
                        {
                            p[i].gg++;
                            p[i].use[j]=0;
                        }
                    }else if(p[i].shoupai[j]=='F')
                    {
                        if(p[i].shili==2)
                        {
                            p[i].use[j]=0;
                            tiao[i]=1;
                            lei_fan_zhu[i]=0;
                            bool safe=0;
                            for(int to=i%n+1;to!=i;to=(to==n)?1:to+1)
                            {
                                if(p[to].shili==1)
                                {
                                    if(push_J(to))
                                    {
                                        safe=1;
                                        break;
                                    }
                                }
                            }
                            if(safe)continue;
                            while(1)
                            {
                                if(!p[1].push_K())
                                {
                                    p[1].gg--;
                                    if(p[1].gg<=0)
                                    {
                                        if(!p[1].push_P())print();
                                    }
                                    break;
                                }
                                if(!p[i].push_K())
                                {
                                    p[i].gg--;
                                    if(p[i].gg<=0)
                                    {
                                        if(!p[i].push_P())dead(1,i);
                                    }
                                    break;
                                }
                            }
                            j=p[i].l-1;
                        }else if(i==1)
                        {
                            for(int to=2;to<=n;to++)
                            {
                                if(p[to].gg<=0)continue;
                                if(lei_fan_zhu[to]&&p[i].shili==1)
                                {
                                    p[i].use[j]=0;
                                    p[to].gg--;
                                    if(p[to].gg<=0)if(!p[to].push_P())dead(1,to);
                                    j=p[i].l-1;
                                    break;
                                }
                                if((tiao[to]&&p[to].shili==2)||lei_fan_zhu[to])
                                {
                                    p[i].use[j]=0;
                                    bool safe = 0;
                                    if(tiao[to])
                                    {
                                        for(int sec=2;sec<=n;sec++)
                                        {
                                            if(p[sec].shili==p[to].shili&&p[sec].gg>0)
                                            {
                                                if(push_J(sec))
                                                {
                                                    safe=1;
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                    if(safe)break;
                                    while(1)
                                    {
                                        if(!p[to].push_K())
                                        {
                                            p[to].gg--;
                                            if(p[to].gg<=0)
                                            {
                                                if(!p[to].push_P())dead(1,to);
                                            }
                                            break;
                                        }
                                        tiao[to]=1,lei_fan_zhu[to]=0;
                                        if(!p[1].push_K())
                                        {
                                            p[1].gg--;
                                            if(p[1].gg<=0)
                                            {
                                                if(!p[to].push_P())print();
                                            }
                                            break;
                                        }
                                    }
                                    j=p[i].l-1;
                                    break;
                                }
                            }
                        }else
                        {
                            for(int to=i%n+1;to!=i;to=(to==n)?1:to+1)
                            {
                                if(p[to].gg<=0)continue;
                                if(!tiao[to])continue;
                                if(p[to].shili==1)continue;
                                p[i].use[j]=0;
                                lei_fan_zhu[i]=0;
                                tiao[i]=1;
                                bool safe=0;
                                for(int sec=i%n+1;sec!=i;sec=(sec==n)?1:sec+1)
                                {
                                    if(p[sec].gg<=0)continue;
                                    if(p[sec].shili==p[to].shili&&p[sec].gg>0)
                                    {
                                        if(push_J(sec))
                                        {
                                            safe=1;
                                            break;
                                        }
                                    }
                                }
                                if(safe)break;
                                while(1)
                                {
                                    if(!p[to].push_K())
                                    {
                                        p[to].gg--;
                                        if(p[to].gg<=0)
                                        {
                                            if(!p[to].push_P())dead(i,to);
                                        }
                                        break;
                                    }
                                    if(!p[i].push_K())
                                    {
                                        p[i].gg--;
                                        if(p[i].gg<=0)
                                        {
                                            if(!p[i].push_P())dead(to,i);
                                        }
                                        break;
                                    }
                                }
                                j=p[i].l-1;
                                break;
                            }
                        }
                    }else if(p[i].shoupai[j]=='K')
                    {
                        if(i!=1)
                        {
                            if(push_Kill&&!p[i].nu)continue;
                            if(!tiao[p[i].hit])continue;
                            if(p[p[i].hit].shili==p[i].shili)continue;
                            p[i].use[j]=0;
                            push_Kill=1;
                            lei_fan_zhu[i]=0;
                            tiao[i]=1;
                            if(!p[p[i].hit].push_D())
                            {
                                p[p[i].hit].gg--;
                                if(p[p[i].hit].gg<=0)
                                {
                                    if(!p[p[i].hit].push_P())dead(i,p[i].hit);
                                }
                            }
                            j=p[i].l-1;
                        }else
                        {
                            if(push_Kill&&!p[i].nu)continue;
                            if(tiao[p[i].hit]&&p[p[i].hit].shili==1)continue;
                            if(!tiao[p[i].hit]&&!lei_fan_zhu[p[i].hit])continue;
                            p[i].use[j]=0;
                            push_Kill=1;
                            if(!p[p[i].hit].push_D())
                            {
                                p[p[i].hit].gg--;
                                if(p[p[i].hit].gg<=0)
                                {
                                    if(!p[p[i].hit].push_P())dead(i,p[i].hit);
                                }
                            }
                            j=p[i].l-1;
                        }
                    }
                }
                while(p[i].use[p[i].l]==0&&p[i].l!=p[i].r)p[i].l=(p[i].l==5000)?1:p[i].l+1;
                while(p[i].use[p[i].r]==0&&p[i].l!=p[i].r)p[i].r=(p[i].r==1)?5000:p[i].r-1;
            }
        }
        print();
        return 0;
    }
  • 相关阅读:
    韦到头打印链表
    字符串替换
    二维数组中的查找
    字符串加解密
    简单密码破解
    vue中store模块化
    使用requests抓取网页内容
    PyQt中的一些小问题
    微信公众号之Token验证
    编译BOOST中的PYTHON模块
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/9895395.html
Copyright © 2011-2022 走看看