[SDOI2010]猪国杀

猪国杀

https://ac.nowcoder.com/acm/problem/210160

暴力模拟。
认真读题,并将所有信息列在草稿中。对于这种大模拟。
代码里有一些必要的注释。

#include<bits/stdc++.h>
using namespace std;
const int N=2050,M=25;
int n;
int fpcout;//反猪数目.
bool missionFinished;//游戏结束.
int totcard,nowcard;//总牌数,现取牌数.
char cardset[N],identify[M];//以'U'来表示未知,'L'表示类反.
struct Player{
    bool army;//猪哥连弩.
    int cout,hp,nxt,prv;
    char identify,cards[N];
}a[N];
void getcard(int id){
    if(nowcard==totcard) nowcard--;
    a[id].cards[++a[id].cout]=cardset[++nowcard];
    return ;
}
void clear(int id){
    a[id].cout=0;
    a[id].army=false;
    memset(a[id].cards,0,sizeof a[id].cards);
    return ;
}
void killplayer(int killedid,int killerid){
    //尝试 桃.
    for(int i=1; i<=a[killedid].cout; ++i){
        if(a[killedid].cards[i]=='P'){
            a[killedid].cards[i]=0;
            a[killedid].hp++;
            return ;
        }
    }
    //没有.
    //更换顺序.
    a[a[killedid].prv].nxt=a[killedid].nxt;
    a[a[killedid].nxt].prv=a[killedid].prv;
    if(a[killedid].identify=='M'){//mission failed.
        missionFinished=true;
        return ;
    }
    if(a[killedid].identify=='F'){
        fpcout--;
        if(fpcout==0){//mission complete
            missionFinished=true;
            return ;
        }
        getcard(killerid);
        getcard(killerid);
        getcard(killerid);
    }
    if(a[killedid].identify=='Z' && a[killerid].identify=='M') clear(killerid);
    return ;
}
void attack(int attackedid,int attackerid){
    //尝试 闪.
    for(int i=1; i<=a[attackedid].cout; ++i){
        if(a[attackedid].cards[i]=='D'){
            a[attackedid].cards[i]=0;
            return ;
        }
    }
    //没有闪.
    --a[attackedid].hp;
    if(a[attackedid].hp==0) killplayer(attackedid,attackerid);
    return ;
}
bool unattackable(int attackerid,int attackedid,bool mode){//能跳则跳.
    //printf("%d %d %d\n",attackerid,attackedid,mode);
    bool flag=true;
    for(int i=attackerid; i!=attackerid||flag; i=a[i].nxt){
        flag=false;
        if(mode==1){
            //献殷勤.
            if((a[i].identify==identify[attackedid]) || (a[i].identify=='Z' && identify[attackedid]=='M') || (a[i].identify=='M' && identify[attackedid]=='Z')){
                for(int j=1; j<=a[i].cout; ++j){
                    if(a[i].cards[j]=='J'){
                        a[i].cards[j]=0;
                        identify[i]=a[i].identify;
                        return !unattackable(i,attackerid,!mode);
                    }
                }
            }
        }else{
            //表敌意.
            if(((a[i].identify=='Z' || a[i].identify=='M') && identify[attackerid]=='F') || (a[i].identify=='F' && (identify[attackerid]=='Z' || identify[attackerid]=='M'))){
                for(int j=1; j<=a[i].cout; ++j){
                    if(a[i].cards[j]=='J'){
                        a[i].cards[j]=0;
                        identify[i]=a[i].identify;
                        return !unattackable(i,attackerid,mode);
                    }
                }
            }
        }
    }
    return false;
}
void invasion(int invader,char way){
    for(int i=a[invader].nxt; i!=invader; i=a[i].nxt){
        if(unattackable(invader,i,1)==false){
            int j=0;
            for(j=1; j<=a[i].cout; ++j){
                if(a[i].cards[j]==way){
                    a[i].cards[j]=0;
                    break;
                }
            }
            if(j>a[i].cout){
                a[i].hp--;
                if(i==1 && identify[invader]==0) identify[invader]='L';
                if(a[i].hp==0) killplayer(i,invader);
                if(missionFinished==true) return ;
            }
        }
    }
    return ;
}
void fight(int fightedid,int fighterid){
    if(unattackable(fighterid,fightedid,1)==false){
        if(fighterid==1 && a[fightedid].identify=='Z'){//忠猪不会抵抗主猪的决斗.
            --a[fightedid].hp;
            if(a[fightedid].hp==0) killplayer(fightedid,fighterid);
        }
        else{
            int j=1,k=1;//两人目前枚举到的牌的位置.
            while(1){
                while(j<=a[fightedid].cout && a[fightedid].cards[j]!='K') ++j;
                if(j<=a[fightedid].cout) a[fightedid].cards[j]=0;//出杀.
                else{
                    --a[fightedid].hp;
                    if(a[fightedid].hp==0) killplayer(fightedid,fighterid);
                    break;
                }
                while(k<=a[fighterid].cout && a[fighterid].cards[k]!='K') ++k;
                if(k<=a[fighterid].cout) a[fighterid].cards[k]=0;
                else{
                    --a[fighterid].hp;
                    if(a[fighterid].hp==0) killplayer(fighterid,fightedid);
                    break;
                }
            }
        }
    }
    return ;
}
void start(){
    missionFinished=false;
    if(fpcout==0) return ;//无反猪,主猪胜.
    for(int i=1; i; i=a[i].nxt){
        getcard(i);
        getcard(i);
        bool attacked=false;//是否已经使用过杀.
        for(int j=1; j<=a[i].cout; ++j){
            if(a[i].cards[j]!=0){
                if(a[i].hp==0) break;
                char nowcard=a[i].cards[j];
                if(nowcard=='P' && a[i].hp<4){
                    a[i].hp++;
                    a[i].cards[j]=0;
                }
                else if(nowcard=='K' && (a[i].army==true || attacked==false)){
                    if(a[i].identify=='Z' && identify[a[i].nxt]!='F') continue;
                    if(a[i].identify=='M' && identify[a[i].nxt]!='F' && identify[a[i].nxt]!='L') continue;
                    if(a[i].identify=='F' && identify[a[i].nxt]!='Z' && identify[a[i].nxt]!='M') continue;
                    a[i].cards[j]=0;
                    attack(a[i].nxt,i);
                    attacked=true;
                    identify[i]=a[i].identify;//暴露身份.
                    if(missionFinished==true) return ;
                }
                else if(nowcard=='F'){
                    if(a[i].identify=='F'){//优先攻击主猪.
                        a[i].cards[j]=0;
                        fight(1,i);
                        identify[i]='F';
                        if(missionFinished==true) return ;
                        j=0;//recheck.
                    }else{
                        for(int k=a[i].nxt; k!=i; k=a[k].nxt){//寻找'F','L'.
                            if((a[i].identify=='Z' && identify[k]=='F') || (a[i].identify=='M' && (identify[k]=='F' || identify[k]=='L'))){
                                a[i].cards[j]=0;
                                fight(k,i);
                                identify[i]=a[i].identify;
                                if(missionFinished==true) return ;
                                j=0;
                                break;
                            }
                        }
                    }
                }
                else if(nowcard=='Z'){
                    a[i].cards[j]=0;
                    a[i].army=true;
                    j=0;
                }
                else if(nowcard=='W'){
                    a[i].cards[j]=0;
                    invasion(i,'D');
                    if(missionFinished==true) return ;
                    j=0;
                }
                else if(nowcard=='N'){
                    a[i].cards[j]=0;
                    invasion(i,'K');
                    if(missionFinished==true) return ;
                    j=0;
                }
            }
        }
    }
    return ;
}
void over(){
    puts(a[1].hp<=0 ? "FP" : "MP");
    for(int i=1 ; i<=n; ++i){
        if(a[i].hp<=0) puts("DEAD");
        else{
            for(int j=1; j<=a[i].cout; ++j)
                if(a[i].cards[j]!=0) printf("%c ",a[i].cards[j]);
            printf("\n");
        }
    }
    return ;
}
void Init(){
    for(int i=1; i<=n; ++i){
        a[i].nxt=i+1;
        a[i].prv=i-1;
    }
    a[n].nxt=1,a[1].prv=n;
    static char buf[1000005];
    for(int i=1; i<=n; ++i){
        scanf("%s",buf);//读取身份.
        a[i].identify=buf[0];
        for(int j=1; j<=4; ++j){
            scanf("%s",buf);
            a[i].cards[j]=buf[0];
        }
        a[i].cout=a[i].hp=4;
        if(a[i].identify=='F') fpcout++;//记录反猪数目.
    }
//    printf("%d\n",fpcout);
    identify[1]='M';//1号为主猪.
    for(int i=1; i<=totcard; ++i){
        scanf("%s",buf);
        cardset[i]=buf[0];
    }
    return ;
}
int main(){
    scanf("%d%d",&n,&totcard);
    Init();
    start();
    over();
    return 0;
}
全部评论
问下🐖国杀这种大模拟才3星???
点赞 回复 分享
发布于 2020-12-29 20:26

相关推荐

11-24 00:11
已编辑
广东工业大学 算法工程师
避雷深圳&nbsp;&nbsp;yidao,试用期&nbsp;6&nbsp;个月。好嘛,试用期还没结束,就直接告诉你尽快找下一家吧,我谢谢您嘞
牛客75408465号:笑死,直属领导和 hr 口径都没统一,各自说了一些离谱的被裁理由,你们能不能认真一点呀,哈哈哈哈哈😅😅😅
点赞 评论 收藏
分享
shtdbb_:还不错,没有让你做了笔试再挂你
点赞 评论 收藏
分享
10-05 23:02
东北大学 Java
我说句实话啊:那时候看三个月培训班视频,随便做个项目背点八股,都能说3 40w是侮辱价
点赞 评论 收藏
分享
评论
1
收藏
分享
牛客网
牛客企业服务