[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;
}
原文地址:https://www.cnblogs.com/LiGuanlin1124/p/9895395.html