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

    [SDOI2010]猪国杀 题解

    Problem

    ​ 见原题面

    Solution

    ​ 大模拟,前后共花了一天多一点写完,点几个需要注意的细节:

    ​ 1.注意献殷勤和表敌意在出无懈可击时的差异,具体见代码

    ​ 2.注意AOE伤害中途游戏结束不会继续结算这个AOE伤害

    ​ 3.注意反猪有决斗的话必先对主猪使用

    ​ 4.注意打出无懈可击的顺序,必须沿逆时针模拟

    Code

    #include<bits/stdc++.h>
    using namespace std;
    
    int n,m;
    
    class Cards{ 
    
        public:
    
            char GetCard(){
                return tot==m?P[m]:P[tot++];
            }
    
            bool IsCard(char c){
                return c=='P'||c=='K'||c=='D'||c=='F'||c=='N'||c=='W'||c=='J'||c=='Z';
            }
    
            void Initialize(){
                tot=1;
                for(register int i=1;i<=m;++i){
                    char ch=getchar();
                    while(!IsCard(ch))
                        ch=getchar();
                    P[i]=ch;
                }
            }
    
        private:
    
            int tot;
            char P[2005];
    
    }H;
    
    class Pig{
    
        public:
    
            int GetId(){
                return Id;
            }
    
            int HPNow(){
                return HP;
            }
    
            int CardNum(){
                return C.size();
            }
    
            int Relation(int i){
                return I[i-1];
            }
    
            char FindCard(int i){
                return C[i];
            }
    
            bool IsDead(){
                return Dead;
            }
    
            bool IsEquip(){
                return Crossbow;
            }
    
            bool Have(char c){
                for(register int i=0;i<C.size();++i){
                    if(C[i]==c)
                        return 1;
                }
                return 0;
            }
    
            bool IsCard(char c){
                return c=='P'||c=='K'||c=='D'||c=='F'||c=='N'||c=='W'||c=='J'||c=='Z';
            }
    
            void Hurt(){
                if(!--HP){
                    if(Have('P')){
                        HP=1;
                        Delt('P');
                    }
                    else
                        Dead=1;
                }
            }
    
            void Equip(){
                Crossbow=1;
            }
    
            void Print(){
                for(register int i=0;i<C.size();++i){
                    putchar(C[i]);
                    putchar(' ');
                }
            }
    
            void Discard(){
                C.clear();
                Crossbow=0;
            }
    
            void Recover(){
                ++HP;
            }
    
            void Delt(char c){
                vector<char>::iterator IT;
                for(IT=C.begin();IT!=C.end();++IT){
                    if(*IT==c){
                        C.erase(IT);
                        break;
                    }
                }
            }
    
            void Getcards(int i){
                while(i--)
                    C.push_back(H.GetCard());
            }
    
            void SetId(int i,int k){
                I[i-1]=k;
            }
    
            void Initialize(int Now){
                HP=4;Pos=Now;
                char s[2];scanf("%s",s);
                if(s[0]=='M')
                    Id=0;
                if(s[0]=='F')
                    Id=-1;
                if(s[0]=='Z')
                    Id=+1;
                for(register int i=1;i<=4;++i){
                    char ch=getchar();
                    while(!IsCard(ch))
                        ch=getchar();
                    C.push_back(ch);
                }
                for(register int i=1;i<=n;++i)
                    I.push_back(0);
            }
    
        private:
    
            int HP;                     //当前血量
            int Id;                     //自身身份
            int Pos;                    //自身位置
            bool Dead;                  //是否死亡
            bool Crossbow;              //诸葛连弩
            vector<int >I;              //他人身份
            vector<char>C;              //当前手牌
    
    }P[15];
    
    int Find(int K,int T,int flag){
        int Pos=0;
        for(register int i=K;i<=n;++i){
            if(Pos)
                break;
            if(!P[i].IsDead()&&((flag==1&&P[i].Relation(K)==-1)||(flag!=1&&P[i].Relation(T)==+1))&&P[i].Have('J')){
                Pos=i;
                break;
            }
        }
        for(register int i=1;i< K;++i){
            if(Pos)
                break;
            if(!P[i].IsDead()&&((flag==1&&P[i].Relation(K)==-1)||(flag!=1&&P[i].Relation(T)==+1))&&P[i].Have('J')){
                Pos=i;
                break;
            }       
        }
        return Pos;
    }
    
    void ResetId(int K,int T,int op){
        for(register int i=1;i<=n;++i){
            if(i==K)
                P[i].SetId(i,1);
            if(i!=K){
                if(!P[i].Relation(K))
                    P[i].SetId(K,op*P[i].Relation(T));
                if(!P[i].GetId()&&P[i].Relation(K)!=+1)
                    P[i].SetId(K,op*P[i].Relation(T));
            }
        }   
        return;
    }
    
    bool Offset(int From,int To,int flag){
        int Able=1,Pos=Find(From,To,flag);
        if(flag)
            ResetId(From,To,-1);
        flag=1;
        while(Pos){
            Able^=1;
            ResetId(Pos,To,flag);
            if(flag==-1)
                To=From;
            From=Pos;
            P[Pos].Delt('J');
            Pos=Find(From,To,flag);
            if(Pos)
                flag=P[Pos].Relation(To)==1?+1:-1;
        }
        return Able;
    }
    
    bool CheckOver(int flag){
        int Num[3]={0,0,0};
        for(register int i=1;i<=n;++i){
            if(!P[i].IsDead())
                ++Num[P[i].GetId()+1];
        }
        if(!Num[0]){
            if(flag)
                printf("MP
    ");
            return 1;
        }
        if(!Num[1]){
            if(flag)
                printf("FP
    ");
            return 1;
        }
        return 0;
    }
    
    bool Kill(int K){
        int T=K%n+1;
        while(P[T].IsDead())
            T=T%n+1;
        if(P[K].Relation(T)!=-1)
            return 0;
        ResetId(K,T,-1);
        if(P[T].Have('D'))
            P[T].Delt('D');
        else{
            P[T].Hurt();
            if(CheckOver(0))
                return 1;
            if(P[T].IsDead()){
                if(P[T].GetId()==-1)
                    P[K].Getcards(3);
                if(!P[K].GetId()&&P[T].GetId()==+1)
                    P[K].Discard();
            }
        }
        return 1;
    }
    
    bool Duel(int K){
        int T;
        if(P[K].GetId()==-1){
            for(register int i=1;i<=n;++i){
                if(!P[i].GetId()){
                    T=i;
                    break;
                }
            }
        }
        else{
            T=K%n+1;
            while(P[T].IsDead()||P[K].Relation(T)!=-1){
                T=T%n+1;
                if(T==K)
                    break;
            }
        }
        if(T==K)
            return 0;
        if(Offset(K,T,-1)){
            if(!P[K].GetId()&&P[T].GetId()==+1){
                P[T].Hurt();
                if(P[T].IsDead())
                    P[K].Discard();
            }
            else{
                int Now=T,Last=K;
                while(P[Now].Have('K')){
                    P[Now].Delt('K');
                    swap(Now,Last);
                }
                P[Now].Hurt();
                if(CheckOver(0))
                    return 1;
                if(P[Now].IsDead()&&P[Now].GetId()==-1)
                    P[Last].Getcards(3);
            }
        }
        return 1;
    }
    
    void AOE(int K,char c){
        for(register int i=K+1;i<=n;++i){
            if(P[i].IsDead())
                continue;
            if(Offset(K,i,0)){
                if(P[i].Have(c))
                    P[i].Delt(c);
                else{
                    if(!P[i].GetId()&&P[i].Relation(K)!=+1)
                        P[i].SetId(K,-1);
                    P[i].Hurt();
                    if(CheckOver(0))
                        break;
                    if(P[i].IsDead()){
                        if(!P[K].GetId()&&P[i].GetId()==+1)
                            P[K].Discard();
                        if(P[i].GetId()==-1)
                            P[K].Getcards(3);
                    }
                }
            }
        }
        if(CheckOver(0))
            return;
        for(register int i=0+1;i< K;++i){
            if(P[i].IsDead())
                continue;
            if(Offset(K,i,0)){
                if(P[i].Have(c))
                    P[i].Delt(c);
                else{
                    if(!P[i].GetId()&&P[i].Relation(K)!=+1)
                        P[i].SetId(K,-1);
                    P[i].Hurt();
                    if(CheckOver(0))
                        break;
                    if(P[i].IsDead()){
                        if(!P[K].GetId()&&P[i].GetId()==+1)
                            P[K].Discard();
                        if(P[i].GetId()==-1)
                            P[K].Getcards(3);
                    }
                }
            }
        }
        return;
    }
    
    void Play(int K){
        int Now=0,Flag=0;
        P[K].Getcards(2);
        while(!P[K].IsDead()){
            if(Now>=P[K].CardNum())
                break;
            char c=P[K].FindCard(Now++);
            if(c=='D')
                continue;
            if(c=='J')
                continue;
            if(c=='P'){
                if(P[K].HPNow()<4){
                    Now=0;
                    P[K].Delt('P');
                    P[K].Recover();
                }
            }
            if(c=='K'){
                if(!Flag||P[K].IsEquip()){
                    if(Kill(K)){
                        Now=0;
                        Flag=1;
                        P[K].Delt('K');
                    }
                }
            }
            if(c=='Z'){
                Now=0;
                P[K].Equip();
                P[K].Delt('Z');
            }
            if(c=='F'){
                if(Duel(K)){
                    Now=0;
                    P[K].Delt('F');
                }
            }
            if(c=='W'){
                Now=0;
                AOE(K,'D');
                P[K].Delt('W');
            }
            if(c=='N'){
                Now=0;;
                AOE(K,'K');
                P[K].Delt('N');
            }
            if(CheckOver(0))
                break;
        }
        return;
    }
    
    void work(){
        while(true){
            for(register int K=1;K<=n;++K){
                if(P[K].IsDead())
                    continue;
                Play(K);
                if(CheckOver(0))
                    break;
            }
            if(CheckOver(1))
                break;
        }
        for(register int i=1;i<=n;++i){
            if(P[i].IsDead())
                printf("DEAD
    ");
            else{
                P[i].Print();
                putchar('
    ');
            }
        }
        return;
    }
    
    inline int read(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){
           if(ch=='-')f=-1;
           ch=getchar();
        }
        while(ch>='0'&&ch<='9'){
           x=(x<<1)+(x<<3)+ch-'0';
           ch=getchar();
        }
        return x*f;
    }
    
    int main(){
    
        n=read();m=read();
    
        for(register int i=1;i<=n;++i)
            P[i].Initialize(i);
    
        int MP=0;
        for(register int i=1;i<=n;++i){
            if(!P[i].GetId())
                MP=i;
        }
    
        for(register int i=1;i<=n;++i)
            P[i].SetId(MP,P[i].GetId());
    
        P[MP].SetId(MP,1);
    
        H.Initialize();
    
        work();
    
        return 0;
    }
    
  • 相关阅读:
    【BZOJ3518】点组计数 欧拉函数
    【BZOJ3677】[Apio2014]连珠线 换根DP
    【BZOJ3678】wangxz与OJ Splay
    【BZOJ3935】Rbtree 树形DP
    【BZOJ3958】[WF2011]Mummy Madness 二分+扫描线+线段树
    (转)Jquery中$.get(),$.post(),$.ajax(),$.getJSON()的用法总结
    string.Format出现异常"输入的字符串格式有误"的解决方法
    c# winForm使用Aspose.Cells读取CSV文件中文乱码问题
    PowerDesigner15.1给自定义架构表字段添加MS_Description出错
    MongoDB 多条件组合查询
  • 原文地址:https://www.cnblogs.com/zjy123456/p/13955541.html
Copyright © 2011-2022 走看看