1972: [Sdoi2010]猪国杀

3 篇文章 0 订阅
2 篇文章 0 订阅

来道大模拟
oi生涯中写过最长代码


#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<algorithm>
#include<deque>
#include<queue>
#define rep(i,k,n) for(int i=k;i<=(n);i++)
#define rep2(i,k,n) for(int i=k;i>=(n);i--)
using namespace std;
int T=0,n,m;
int hash(char c){
    if(c=='P')return 1;
    if(c=='K')return 2;
    if(c=='D')return 3;
    if(c=='F')return 4;
    if(c=='N')return 5;
    if(c=='W')return 6;
    if(c=='J')return 7;
    if(c=='Z')return 8;
}
char nihash(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';
}
int hash_person(char c){
    if(c=='M')return 1;
    if(c=='Z')return 3;
    if(c=='F')return 2;
}
struct pai{
    int op,ti;
    bool use;
    pai(int op=0,int ti=0,bool use=false):op(op),ti(ti),use(use){}
};
queue<pai> dump;

bool cmp_use(pai a,pai b){
    return a.use<b.use;
}
bool cmp_t(pai a,pai b){
    return a.ti<b.ti;
}
struct player{
    int op,Hp;
    bool jump;
    bool dead;
    bool weapon;
    bool lei;
    int last;
    vector<pai> hand;
    player(){Hp=4;lei=false;weapon=false;jump=false;dead=false;hand.clear();}
}P[15];
void debug(){
    rep(i,1,n){//printf("%d op:%d Hp:%d jump:%d lei:%d weapon:%d:",i,P[i].op,P[i].Hp,P[i].jump,P[i].lei,P[i].weapon);
        if(P[i].dead)printf("DEAD");
        else{
            sort(P[i].hand.begin(),P[i].hand.end(),cmp_t);
            for(int j=0;j<P[i].hand.size();j++){
                pai v=P[i].hand[j];
               if(!v.use)printf("%c ",nihash(v.op));
            }
        }
        printf("\n");
    }
    printf("\n");
}
void mo(int x){
    P[x].hand.push_back(dump.front());
    if(dump.size()>1)dump.pop();
}
void tao(int x){
    if(P[x].Hp>0)return;
    for(int i=0;i<P[x].hand.size();i++){
    pai& kk=P[x].hand[i];
    if(kk.use)continue;
    if(kk.op==1){
        P[x].Hp++,kk.use=true;break;
    }
    }
}
bool sha(int x){
    for(int i=0;i<P[x].hand.size();i++){
    pai& kk=P[x].hand[i];
    if(kk.use)continue;
    if(kk.op==2){
        kk.use=true;return true;
    }
    }
    return false;
}
bool shan(int x){
    for(int i=0;i<P[x].hand.size();i++){
    pai& kk=P[x].hand[i];
    if(kk.use)continue;
    if(kk.op==3){
        kk.use=true;return true;
    }
    }
    return false;
}
bool wu(int x){
    for(int i=0;i<P[x].hand.size();i++){
        pai& kk=P[x].hand[i];
        if(kk.use)continue;
        if(kk.op==7){
            kk.use=true;P[x].jump=true;return true;
        }
    }
    return false;
}
bool pan(){
    if(P[1].dead)return true;
    rep(i,1,n)if(!P[i].dead && P[i].op==2)return false;
    return true;
}
void revenge(int x,int goal){
    if(P[goal].op==2)
    mo(x),mo(x),mo(x);
    if(P[goal].op==3 && P[x].op==1){
        P[x].hand.clear();
        P[x].weapon=false;
    }
}
bool shang(int x,int goal){
        P[goal].Hp--;
        tao(goal);
        if(!P[goal].Hp){
        P[goal].dead=true;
        if(pan())return true;
        revenge(x,goal);
        }
        return false;
}
int dis(int x,int y){
    int res=0;
    rep(i,1,n-1){
        int v=(x+i-1)%n+1;
        if(P[v].dead)continue;
        res++;
        if(v==y)return res;
    }
}
bool iron(int x,int goal,int k){
    if(!P[goal].jump)return false;
     rep(j,0,n-1){
         int v=(x+j-1)%n+1;
         if(P[v].dead)continue;
         if(k==1){
            if((P[v].op+P[goal].op==4 || P[v].op==P[goal].op) && wu(v) && !iron(v,goal,k^1))return true;
         }
         if(k==0){
            if((P[v].op+P[goal].op!=4 && P[v].op!=P[goal].op) && wu(v) && !iron(v,goal,k^1))return true;
         }
     }
     return false;
}
bool jvedou(int x,int y){
    if(P[x].op==1 && P[y].op==3)shang(x,y);
    else{
        for(;;){
            if(!sha(y)){if(shang(x,y))return true;return false;}
            if(!sha(x)){if(shang(y,x))return true;return false;}
        }
    }
}
int enemy(int x){
    rep(i,1,n-1){
        int v=(x+i-1)%n+1;
        if(P[v].dead)continue;
        if(x==1 && !P[v].jump && P[v].lei)return v;
        else if(!P[v].jump)continue;
        else if(P[v].op==P[x].op)continue;
        else if(P[x].op+P[v].op!=4)return v;
    }
    return 0;
}
void zhengli(int x){
        sort(P[x].hand.begin(),P[x].hand.end(),cmp_use);
        int len=P[x].hand.size();
        while(len && P[x].hand[len-1].use)P[x].hand.pop_back(),len--;
}
void play(int x){
    if(P[x].dead)return;
    sort(P[x].hand.begin(),P[x].hand.end(),cmp_t);
    mo(x),mo(x);
    int vis=0;
    int ok=1;
    do{
    if(P[x].dead)return;
    ok=0;
    for(int i=0;i<P[x].hand.size();i++){

        pai& kk=P[x].hand[i];
        if(kk.use)continue;
        else if(kk.op==1 && P[x].Hp<4){P[x].Hp++;kk.use=true;ok=1;break;}
        else if(kk.op==2 && (!vis || P[x].weapon)){
            int goal=enemy(x);
            if(!goal)continue;
            if(dis(x,goal)!=1)continue; 
            P[x].jump=true;
            kk.use=true;
            vis=1;
            ok=1;
            if(!shan(goal)){
                if(shang(x,goal)){ok=0;break;}   
            }
            break;
       }
        else if(kk.op==4){
            int goal=enemy(x);
            if(P[x].op==2)goal=1;
            if(!goal)continue;
            P[x].jump=true;
            kk.use=true;
            ok=1;
            if(iron(x,goal,1))continue;
            if(jvedou(x,goal)){ok=0;break;}
            break; 
        }
        else if(kk.op==5){
            P[x].lei=true;
            kk.use=true;
            ok=1;
            rep(j,1,n-1){int goal=(x+j-1)%n+1;
                if(P[goal].dead)continue;
                if(iron(x,goal,1))continue;
                if(sha(goal))continue;
                if(shang(x,goal)){ok=0;break;} 
            }
            break;
        }
        else if(kk.op==6){
            P[x].lei=true;
            kk.use=true;
            ok=1;
            rep(j,1,n-1){int goal=(x+j-1)%n+1;
                if(P[goal].dead)continue;
                if(iron(x,goal,1))continue;
                if(shan(goal))continue;
                if(shang(x,goal)){ok=0;break;} 
            }
            break;
        }
        else if(kk.op==8){
            kk.use=1;P[x].weapon=true;ok=1;break;
        }
    }
    }while(ok);
    zhengli(x);
}
void check(){
    if(P[1].dead)printf("FP\n");
    else printf("MP\n");
    rep(i,1,n){
        if(P[i].dead)printf("DEAD");
        else{zhengli(i);
            sort(P[i].hand.begin(),P[i].hand.end(),cmp_t);
            for(int j=0;j<P[i].hand.size();j++){
                pai v=P[i].hand[j];
                if(j)printf(" "); 
                printf("%c",nihash(v.op));
            }
        }
        printf("\n");
    }
}
int main(){
    scanf("%d%d",&n,&m);
    char s[10];
    rep(i,1,n){
       scanf("%s",s);P[i].op=hash_person(s[0]);
       rep(j,1,4){
           scanf("%s",s);P[i].hand.push_back(pai(hash(s[0]),j));
       }
    }P[1].jump=true;
    rep(i,1,m){scanf("%s",s);
       dump.push(pai(hash(s[0]),i+4));
    }
    do{
       rep(i,1,n){if(pan())break;
           play(i);
//         debug();
       }
    }while(!pan());
    check();
    return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值