记录编号 458501 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [SDOI 2010] 猪国杀 最终得分 100
用户昵称 GravatarHzoi_joker 是否通过 通过
代码语言 C++ 运行时间 0.148 s
提交时间 2017-10-11 15:09:00 内存使用 0.33 MiB
显示代码纯文本
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#define N 15
#define M 2105
#define tao 1
#define sha 2
#define shan 3
#define jue 4
#define man 5
#define wan 6
#define wu 7
#define nu 8
using namespace std;
int pre[N],fro[N],n,m,zz;
int st[M],top;//牌堆,注意为0时一直摸最后一张牌
struct pi
{   
    int ip;//身份
    int jump;//是否跳反/忠   
    int q[M],en,hea,hp;//血量
    bool ln;//是否有连弩
}pig[N];
char bbb[20];
void print()
{
    for(int i=1;i<=n;i++)
    {
        cout<<pig[i].hp<<' '<<pig[i].ip<<' '<<pig[i].jump<<endl;
    }
    cout<<endl;
}
void print2()
{
    int now=1;bool yx=1;
    while(now!=1||yx)
    {
        yx=0;
        cout<<now<<' ';
        now=fro[now];
    }
    cout<<endl;
}
void show(int x)
{
    for(int i=pig[x].hea;i<=pig[x].en;i++)
    {
        if(pig[x].q[i])
        {
            cout<<pig[x].q[i]<<' ';
        }
    }
    cout<<endl<<endl;
}
int check(char x)
{   
    if(x=='P') return tao;
    else if(x=='K') return sha;
    else if(x=='D') return shan;
    else if(x=='F') return jue;
    else if(x=='N') return man;
    else if(x=='W') return wan;
    else if(x=='J') return wu;
    else return nu;
}
void get_pok(int x,int js)//第x只猪摸的第js张牌
{
    if(js==3)return;
    if(!top) top=1;
    pig[x].en++;
    pig[x].q[pig[x].en]=st[top];
    top--;
    get_pok(x,js+1);
}
void zl(int x)
{
    for(int j=pig[x].hea;j<=pig[x].en;j++)
    {
        if(pig[x].q[j]!=0)
        {
            pig[x].hea=j;
            for(int k=pig[x].en;k>=pig[x].hea;k--)
            {
                if(pig[x].q[k]!=0)
                {
                    pig[x].en=k;
                    break;
                }
            }
            break;
        }
        if(j==pig[x].en)
        {
            pig[x].en=0;
            pig[x].hea=pig[x].en+1;
        }
    }
}
void come_to_end(int x)
{
    if(x==1)
        printf("MP\n");
    else
        printf("FP\n");
    for(int i=1;i<=n;i++)
    {
        if(pig[i].hp==0) printf("DEAD\n");
        else
        {
            for(int j=pig[i].hea;j<=pig[i].en;j++)
            {
                if(!pig[i].q[j])continue;
                int y=pig[i].q[j];
                if(y==tao)printf("P ");
                else if(y==sha)printf("K ");
                else if(y==shan)printf("D ");
                else if(y==nu) printf("Z ");
                else if(y==jue) printf("F ");
                else if(y==man) printf("N ");
                else if(y==wan) printf("W ");
                else if(y==wu) printf("J ");
            }
            printf("\n");
        }
    }
    exit(0);
}
void gua(int x,int from)//被from打挂了
{
    //cout<<from<<"has killed "<<x<<endl;
    pre[fro[x]]=pre[x];
    fro[pre[x]]=fro[x];
    if(x==1) come_to_end(3);
    int now=fro[1];
    bool yx=1;
    while(now!=1)
    {
        if(pig[now].ip==3)
        {
            yx=0;
            break;
        }
        now=fro[now];
    }
    if(yx)come_to_end(1);
    if(pig[x].ip==2&&pig[from].ip==1)
    {
        memset(pig[from].q,0,sizeof(pig[from].q));
        pig[from].ln=0;
        pig[from].hea=1,pig[from].en=0;
    }
    else if(pig[x].ip==3)
    {
        get_pok(from,0);
    }
}
void lost(int x,int from)//检查是否死透
{
    if(pig[x].hp==0)
    {
        for(int i=pig[x].hea;i<=pig[x].en;i++)
        {
            if(pig[x].q[i]==tao)
            {
                pig[x].hp++;
                pig[x].q[i]=0;
                zl(x);
                return ;
            }
        }
        gua(x,from);
    }
}
void kill(int x)//x对下家出杀
{
    int to=fro[x];
    //cout<<x<<"hit "<<to<<endl;
    bool yx=1;
    for(int i=pig[to].hea;i<=pig[to].en;i++)
    {
        if(pig[to].q[i]==shan)
        {
            pig[to].q[i]=0;
            yx=0;
            zl(to);
            break;
        }
    }
    if(yx)
    {
        pig[to].hp--;
        lost(to,x);
    }
}
bool use_wu(int x)//x使用无懈是否成功
{
    int now=fro[x];
    while(now!=x)
    {
        if((pig[now].ip==3&&pig[x].jump!=3)||(pig[now].ip!=3&&pig[x].jump==3))
        {
            for(int i=pig[now].hea;i<=pig[now].en;i++)
            {
                if(pig[now].q[i]==wu)
                {
                    pig[now].q[i]=0;
                    if(pig[now].ip==3)pig[now].jump=3;
                    else if(pig[now].ip==2) pig[now].jump=2;
                    zl(now);
                    if(use_wu(now)) return 0;
                    else    return 1;
                }
            }
        }
        now=fro[now];
    }
    return 1;
}
void come_to_fight(int x,int y)//x对y决斗
{
    //cout<<x<<" fight with "<<y<<endl;
    int now=fro[x];
    if(pig[y].jump&&pig[y].jump!=-1)
    {
        while(now!=x)
        {
            if((pig[now].ip==3&&pig[y].jump==3)||(pig[y].jump!=3&&pig[now].ip!=3))
            {
                bool yx=1;
                for(int i=pig[now].hea;i<=pig[now].en;i++)
                {
                    if(pig[now].q[i]==wu)
                    {   
                        pig[now].q[i]=0;
                        if(pig[now].ip==3)pig[now].jump=3;
                        else if(pig[now].ip==2) pig[now].jump=2;
                        zl(now);
                        yx=0;
                        if(use_wu(now))return;
                    }
                }
                if(!yx)break;
            }
            now=fro[now];
        }
    }
    if(pig[x].ip==1&&pig[y].ip==2)
    {
        pig[y].hp--;
        lost(y,x);
        return;
    }
    int js1=0,js2=0;
    for(int i=pig[x].hea;i<=pig[x].en;i++)
    {
        if(pig[x].q[i]==sha)
        {
            js1++;
        }
    }
    for(int i=pig[y].hea;i<=pig[y].en;i++)
    {
        if(pig[y].q[i]==sha)
        {
            js2++;
        }
    }
    if(js1<js2)
    {
        int js3=0;
        for(int i=pig[y].hea;i<=pig[y].en;i++)
        {
            if(pig[y].q[i]==sha)
            {
                js3++;
                pig[y].q[i]=0;
                if(js3==js1+1)break;
            }
        }
        for(int i=pig[x].hea;i<=pig[x].en;i++)
        {
            if(pig[x].q[i]==sha)
            {
                pig[x].q[i]=0;  
            }
        }
        zl(x),zl(y);
        pig[x].hp--;
        lost(x,y);
    //  cout<<x<<"failed"<<endl;
    }
    else
    {
        int js3=0;
        for(int i=pig[x].hea;i<=pig[x].en;i++)
        {
            if(pig[x].q[i]==sha)
            {
                if(js3==js2)break;
                js3++;
                pig[x].q[i]=0;
            }
        }
        for(int i=pig[y].hea;i<=pig[y].en;i++)
        {
            if(pig[y].q[i]==sha)
                pig[y].q[i]=0;  
        }
        zl(x),zl(y);
        pig[y].hp--;
        lost(y,x);
    //  cout<<y<<"failed"<<endl;
    }
}
void nanman(int x) //南蛮入侵
{
    //cout<<x<<"has fucked everyone!"<<endl;
    int now=fro[x];
    while(now!=x)
    {
        if(pig[now].jump&&pig[now].jump!=-1)
        {
            bool yx2=0;
             
            int now2=x;
             
            bool yxxx=1;
            while(now2!=x||yxxx)
            {
                yxxx=0;
                if((pig[now2].ip==3&&pig[now].jump==3)||(pig[now2].ip!=3&&pig[now].jump!=3))
                {
                    bool yx=1;
                    for(int i=pig[now2].hea;i<=pig[now2].en;i++)
                    {
                        if(pig[now2].q[i]==wu)
                        {   
                            pig[now2].q[i]=0;
                            if(pig[now2].ip==3)pig[now2].jump=3;
                            else if(pig[now2].ip==2) pig[now2].jump=2;
                            zl(now2);
                            yx=0;
                            if(use_wu(now2))
                            {
                                yx2=1;
                                break;
                            }
                            else break;
                        }
                    }
                    if(!yx)break;
                }
                if(yx2)break;
                now2=fro[now2];
            }
            if(yx2)
            {
                now=fro[now];continue;
            }
        }
        bool yx=1;
        for(int i=pig[now].hea;i<=pig[now].en;i++)
        {
            if(pig[now].q[i]==sha)
            {
 
                pig[now].q[i]=0;
                zl(now);
                yx=0;
                break;
            }
        }
        if(yx)
        {
            pig[now].hp--;
            if(now==1&&!pig[x].jump)pig[x].jump=-1;
            lost(now,x);
        }
        now=fro[now];
    }
}
void wanjian(int x) //万箭齐发
{
    //cout<<x<<"has fucked everyone!"<<endl;
    int now=fro[x];
    while(now!=x)
    {
        if(pig[now].jump&&pig[now].jump!=-1)
        {
            bool yx2=0;
            int now2=x;
            bool yxxx=1;
            while((now2!=x)||yxxx)
            {
                yxxx=0;
                if((pig[now2].ip==3&&pig[now].jump==3)||(pig[now2].ip!=3&&pig[now].jump!=3))
                {
                    bool yx=1;
                    for(int i=pig[now2].hea;i<=pig[now2].en;i++)
                    {
                        if(pig[now2].q[i]==wu)
                        {   
                            pig[now2].q[i]=0;
                            if(pig[now2].ip==3)pig[now2].jump=3;
                            else if(pig[now2].ip==2) pig[now2].jump=2;
                            zl(now2);
                            yx=0;
                            if(use_wu(now2))
                            {
                                yx2=1;
                                break;
                            }
                            else break;
                        }
                    }
                    if(!yx)break;
                }
                if(yx2)break;
                now2=fro[now2];
            }
            if(yx2)
            {
                now=fro[now];continue;
            }
        }
        bool yx=1;
        for(int i=pig[now].hea;i<=pig[now].en;i++)
        {
            if(pig[now].q[i]==shan)
            {
 
                pig[now].q[i]=0;
                zl(now);
                yx=0;
                break;
            }
        }
        if(yx)
        {
            pig[now].hp--;
            if(now==1&&!pig[x].jump)pig[x].jump=-1;
            lost(now,x);
        }
        now=fro[now];
    }
}
void second_stage(int x,int js) //出牌阶段,出了几张杀
{
    //cout<<x<<' '<<js<<endl;
    //print();
    for(int i=pig[x].hea;i<=pig[x].en;i++)
    {
        if(!pig[x].q[i]||pig[x].q[i]==shan||pig[x].q[i]==wu||(pig[x].q[i]==sha&&js&&!pig[x].ln))continue;
        if(pig[x].hp!=4&&pig[x].q[i]==tao)
        {
        //  cout<<x<<"come back to life"<<endl;
            pig[x].hp++;
            pig[x].q[i]=0;
            zl(x);
            second_stage(x,js);
            return;
        }
        else if(pig[x].q[i]==sha)
        {
            if(pig[x].ip==1&&pig[fro[x]].jump&&pig[fro[x]].jump!=2)
            {
                 
                pig[x].q[i]=0; zl(x);
                kill(x);
                second_stage(x,js+1);
                return;
            }
            else if(pig[x].ip==2&&pig[fro[x]].jump==3)
            {
                pig[x].jump=2;
                pig[x].q[i]=0; zl(x);
                kill(x);
                second_stage(x,js+1);
                return;
            }
            else if(pig[x].ip==3&&(pig[fro[x]].jump==1||pig[fro[x]].jump==2))
            {
                 
                pig[x].jump=3;
                pig[x].q[i]=0; zl(x);
                kill(x);
                second_stage(x,js+1);
                return;
            }
        }
        else if(pig[x].q[i]==nu)
        {
            pig[x].q[i]=0;
            pig[x].ln=1;
            zl(x);
            second_stage(x,js);
            return;
        }
        else if(pig[x].q[i]==jue)
        {
            if(pig[x].ip==1)
            {
                int now=fro[1];
                while(now!=1)
                {
                    if(pig[now].jump==-1||pig[now].jump==3)
                    {
                        pig[x].q[i]=0;
                        zl(x);
                        come_to_fight(x,now);
                        if(pig[x].hp==0)return;
                        second_stage(x,js);
                        return;
                        break;
                    }
                    now=fro[now];
                }
            }
            else if(pig[x].ip==2)
            {
                int now=fro[x];
                while(now!=x)
                {
                    if(pig[now].jump==3)
                    {
                        pig[x].q[i]=0;
                        zl(x);
                        pig[x].jump=2;
                        come_to_fight(x,now);
                        if(pig[x].hp==0)return;
                        second_stage(x,js);
                        return;
                        break;
                    }
                    now=fro[now];
                }
            }
            else
            {
                pig[x].jump=3;
                pig[x].q[i]=0;
                zl(x);
                come_to_fight(x,1);
                if(pig[x].hp==0)return;
                second_stage(x,js);
                return;
            }
        }
        else if(pig[x].q[i]==man)
        {
            pig[x].q[i]=0;
            zl(x);
            nanman(x);
            second_stage(x,js);
            return;
        }
        else if(pig[x].q[i]==wan)
        {
            pig[x].q[i]=0;
            zl(x);
            wanjian(x);
            second_stage(x,js);
            return;
        }
    }
}
int main()
{
    freopen("kopk.in","r",stdin);
    freopen("kopk.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        pre[i]=i-1;
        fro[i]=i+1;
        pig[i].hp=4;
        scanf("%s",bbb);
        if(bbb[0]=='M')pig[i].jump=pig[i].ip=1;//主公
        else if(bbb[0]=='Z') pig[i].ip=2;//忠臣
        else pig[i].ip=3;//反贼
        pig[i].hea=1;
        for(int j=1;j<=4;j++)
        {
            scanf("%s",bbb);
            pig[i].en++;
            pig[i].q[pig[i].en]=check(bbb[0]);
        }
    }
    pre[1]=n;
    fro[n]=1;
    top=m;
    for(int i=1;i<=m;i++)
    {
        scanf("%s",bbb);
        st[top-i+1]=check(bbb[0]);
    }
    int now=1;
    while(1)
    {
        get_pok(now,1);//当前猪摸牌
        second_stage(now,0);
        //show(2);
        now=fro[now];
    }
    return 0;
}