记录编号 458682 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [SDOI 2010] 猪国杀 最终得分 100
用户昵称 Gravatarhunter 是否通过 通过
代码语言 C++ 运行时间 0.012 s
提交时间 2017-10-11 18:32:34 内存使用 0.55 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#define maxn 2001
using namespace std;
int n,m;
struct Charator
{
    int rl;
    int he,tl,q[maxn*2];
    int num[9];
    bool v[maxn*2],id;
}a[12];
int tl[12];
int s[maxn],top;
int pre[12],nex[12];
bool ti[12],die[12],zb[12];
bool mark[12];
int  pos_M,die_num,f_num;
bool fail=0;
int getid(char x)
{
    if(x=='P') return 1;
    if(x=='K') return 2;
    if(x=='D') return 3;
    if(x=='F') return 4;
    if(x=='N') return 5;
    if(x=='W') return 6;
    if(x=='J') return 7;
    if(x=='Z') return 8; 
}
char getid2(int x)
{
    if(x==1) return 'P';
    if(x==2) return 'K';
    if(x==3) return 'D';
    if(x==4) return 'F';
    if(x==5) return 'N';
    if(x==6) return 'W';
    if(x==7) return 'J';
    if(x==8) return 'Z';
}
void getp(int x,int n)
{
    while(n--)
    {
        if(!top) top=1;
        a[x].q[a[x].tl++]=s[top];
        a[x].num[s[top]]++; top--;
    } 
}
int getaim(int x)
{
    if(a[x].rl==1)
    {
        for(int i=nex[x];i!=x;i=nex[i])
        if(mark[i]||(ti[i]&&a[i].rl==3)) return i;
        return 0;
    }
    if(a[x].rl==2)
    {
        for(int i=nex[x];i!=x;i=nex[i])
        if(ti[i]&&a[i].rl==3)  return i;
        return 0; 
    }
    if(a[x].rl==3)  return pos_M;
}
void print()
{
    if(fail) printf("FP\n");
    else printf("MP\n");
    for(int i=1;i<=n;i++)
    if(die[i]) printf("DEAD\n");
    else{
        for(int j=a[i].he;j<a[i].tl;j++)
        if(!a[i].v[j]) printf("%c ",getid2(a[i].q[j]));
        printf("\n");
    }
    exit(0);
}
void del(int x)
{
    die[x]=1;
    pre[nex[x]]=pre[x];
    nex[pre[x]]=nex[x];
    if(a[x].rl==1){ fail=1; print(); }
    if(a[x].rl==3) die_num++;
    if(die_num==f_num) print();
}
void qp(int x,int type,int n)
{
    a[x].num[type]-=n;
    for(int i=a[x].he;i<a[x].tl;i++)
    if(!a[x].v[i]&&a[x].q[i]==type){
        a[x].v[i]=1;
        n--;
        if(!n) break;
    }
    while(a[x].v[a[x].he]) a[x].he++;
    return ;
}
void waste()
{
    int x=pos_M;
    a[x].he=a[x].tl; zb[x]=0;
    for(int j=1;j<=8;j++) a[x].num[j]=0;
}
void make_p(int x,int w)
{
    if(w){
        tl[x]++; qp(x,1,1); 
        return ;
    }
    int op=1-tl[x];
    if(op>a[x].num[1]) del(x); 
    else{ qp(x,1,op); tl[x]=1; }
}
void defend_k(int x)
{
    if(a[x].num[3]){  qp(x,3,1);  return ; }
    tl[x]--;
    if(tl[x]<=0) make_p(x,0);
}
void make_k(int x,int aim)
{
    qp(x,2,1);
    ti[x]=1; mark[x]=0; 
    defend_k(aim);
    if(die[aim]&&a[aim].rl==3) getp(x,3);
    if(die[aim]&&a[aim].rl==2&&a[x].rl==1) waste();
    return ;
}  
bool make_j(int x,int type)//当前x出的牌是否有效
{
    int i=x;
    while(1)
    {
        if(a[i].id==type&&a[i].num[7]){
            ti[i]=1; mark[i]=0;
            qp(i,7,1);
            if(make_j(i,type^1)) return 0;
            else return 1;
        }
        i=nex[i];
        if(i==x) break;
    }
    return 1;
}
void make_f(int x,int aim)
{
    qp(x,4,1);
    ti[x]=1; mark[x]=0; 
    bool op=1;
    if(ti[aim]&&!make_j(x,a[aim].id)) op^=1;
    if(!op) return;
    if(a[x].rl==1&&a[aim].rl==2)
    {     
        tl[aim]--;
        if(tl[aim]<=0) make_p(aim,0);
        if(die[aim])  waste();
        return ;
    }
    while(1)
    {
        if(!a[aim].num[2]){
            tl[aim]--;
            if(tl[aim]<=0) make_p(aim,0);
            if(die[aim]&&a[aim].rl==3&&!die[x])  getp(x,3);
            return ;
        } 
        qp(aim,2,1);
        if(!a[x].num[2]){
            tl[x]--;
            if(tl[x]<=0)  make_p(x,0);
            if(die[x]&&a[x].rl==3&&!die[aim])  getp(aim,3);
            return ;
        }
        qp(x,2,1);
    }
    return ;
}
void make_n(int x)
{
    qp(x,5,1);
    for(int i=nex[x];i!=x;i=nex[i])
    {
        if(ti[i]&&!make_j(x,a[i].id)) continue;
        if(a[i].num[2])  qp(i,2,1);
        else{
            tl[i]--;
            if(a[i].rl==1) mark[x]=1;
            if(tl[i]<=0) make_p(i,0);
            if(die[i]&&a[i].rl==3) getp(x,3); 
            if(die[i]&&a[i].rl==2&&a[x].rl==1) waste();
        }
    }
}
void make_w(int x)
{
    qp(x,6,1);
    for(int i=nex[x];i!=x;i=nex[i])
    {
        if(ti[i]&&!make_j(x,a[i].id)) continue;
        if(a[i].num[3])  qp(i,3,1);
        else{
            tl[i]--;
            if(a[i].rl==1) mark[x]=1;
            if(tl[i]<=0) make_p(i,0);
            if(die[i]&&a[i].rl==3) getp(x,3); 
            if(die[i]&&a[i].rl==2&&a[x].rl==1) waste();
        }
    }   
}
void make_z(int x)
{
    qp(x,8,1);  zb[x]=1;
}
void work(int x) 
{
    int t,aim,aim2;
    bool op=0,op1=0;
    getp(x,2);
    while(1)
    {
        if(die[x]) return;    
        op1=0;
        aim=getaim(x);
        for(int i=a[x].he;i<a[x].tl;i++)
        if(!a[x].v[i])
        {
            if(die[x]) return ;
            t=a[x].q[i];
            if(t==2&&a[x].rl==3)
            {
                if(a[nex[x]].id!=a[x].id&&ti[nex[x]]) aim=nex[x];
            }
            if(t==1&&tl[x]==4) continue;
            if(t==3||t==7) continue;
            if(t==2&&(nex[x]!=aim||(op&&!zb[x]))) continue;
            if(t==4&&!aim) continue;
            
            op1=1; 
            if(t==1) make_p(x,i);
            if(t==2) make_k(x,aim),op=1;
            if(t==4) make_f(x,aim);
            if(t==5) make_n(x); 
            if(t==6) make_w(x); 
            if(t==8) make_z(x); 
            break;
        }
        if(die[x]) return ;
        if(!op1) break;
        while(a[x].v[a[x].he]) a[x].he++;
        if(a[x].he>=a[x].tl) break;
    }
    return ;
}
int main()
{
    freopen("kopk.in","r",stdin);
    freopen("kopk.out","w",stdout);
    char type[3]; int x;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%s",type);
        tl[i]=4; 
        if(type[0]=='M'){ a[i].rl=1; pos_M=i; ti[i]=1; }
        if(type[0]=='Z')  a[i].rl=2;
        if(type[0]=='F'){ a[i].rl=3; a[i].id=1; f_num++; }
        for(int j=1;j<=4;j++)
        {
            scanf("%s",type);
            x=getid(type[0]);
            a[i].q[a[i].tl++]=x;
            a[i].num[x]++; 
        }
    }
    for(int i=1;i<=m;i++)
    {
        scanf("%s",type);
        s[m-i+1]=getid(type[0]);
    }
    top=m;
    for(int i=1;i<=n;i++){
        pre[i]=i-1; nex[i]=i+1;
    }
    nex[0]=1;
    pre[1]=n;  nex[n]=1;
    for(int i=nex[0];i<=n;i=nex[i])  work(i); 
    return 0;
}