10分求调
查看原帖
10分求调
542266
cst_123楼主2022/3/25 18:19
#include<bits/stdc++.h>
using namespace std;
#define y 11//宏定义 
#define hh 3000
long long n,mm; 
long long now,APs;
char zgs[hh];
bool js;
long long read(){//快读 
   long long x=0,sg=1;char cha=getchar();
   while(cha<'0'||cha>'9'){if(cha=='-')sg=-1;cha=getchar();}
   while(cha>='0'&&cha<='9'){x=x*10+cha-'0';cha=getchar();}
   return x*sg;
}
struct cst_zhu{
    long long sf;//身份
    long long hp;//生命值 
    long long p;//牌数
    char ca[hh];//牌
    long long q;//前猪
    long long h;//后猪
    long long blsf;//暴露身份
    bool lap;//是否为类反猪
    bool zb;//是否装备武器
}pigg[y];
void cst_dy(long long kk){//打印猪的手牌
    bool to=true;
    for(int i=1;i<=pigg[kk].p;i++){
        if(pigg[kk].ca[i]=='X') continue;
        if(!to) cout<<" ";
        else to=false;
       	printf("%c",pigg[kk].ca[i]);
    }
    cout<<endl;
}
void cst_mo(long long kk){//摸牌
    if(now>mm) now=mm;//牌堆无牌了,不断摸最上面一张
    pigg[kk].p++;
    pigg[kk].ca[pigg[kk].p]=zgs[now];
    now++;//牌堆顶部
}
long long cst_zhao(long long kk,char ch){//第kk头猪 ch 卡牌符号
    for(int i=1;i<=pigg[kk].p;i++)
        if(pigg[kk].ca[i]==ch){
            pigg[kk].ca[i]='X';
            return true;
        }
    return false;
}
void cst_gs3(long long kk,long long ll){//假友关系
    if(pigg[ll].blsf==0) return;//如ll没暴身份 交友无义
    if(pigg[ll].blsf!=3){//否则暴和ll相同身份 要处理类反猪名称 
        pigg[kk].lap=false;
        pigg[kk].blsf=1;
    }
    if(pigg[ll].blsf==3){
        pigg[kk].lap=true;
        pigg[kk].blsf=3;
    }
}
void cst_gs4(long long kk,long long ll){//假敌关系
    if(pigg[ll].blsf==0) return;
    if(pigg[ll].blsf!=3){
        pigg[kk].blsf=3;
        pigg[kk].lap=true;
    }
    if(pigg[ll].blsf==3){
        pigg[kk].blsf=1;
        pigg[kk].lap=false;
    }
}
void cst_sh(long long kk,long long ll){//kk伤害 ll承受伤害
    pigg[ll].hp--;//扣血 
    while(pigg[ll].hp<=0&&cst_zhao(ll,'P')) pigg[ll].hp++;//如有桃就用 
    if(pigg[ll].hp<=0){//如血还没到零就无了 
        pigg[ll].p=0;
        pigg[ll].zb=false;//清空死猪信息 
        if(pigg[ll].sf==1){
            js=true;//主猪死了游戏立刻结束
            return;
        }
        else if(pigg[ll].sf==2){
                if(pigg[kk].sf==1){//主猪杀忠猪 清空主猪手牌
                    pigg[kk].p=0;
                    pigg[kk].zb=false;//清空武器
                }
        }
        else if(pigg[ll].sf==3){
                APs--;//反猪数量减一 
                if(APs==0){//如已没反猪
                    js=true;//游戏结束
                    return;
                }
                cst_mo(kk);//摸牌
                cst_mo(kk);//摸牌
                cst_mo(kk);//摸牌
            }
        pigg[pigg[ll].q].h=pigg[ll].h;//更新前猪后继
        pigg[pigg[ll].h].q=pigg[ll].q;//更新后猪
    }
}
bool cst_gs1(long long kk,long long ll){//真敌关系
    if(pigg[kk].sf==1&&pigg[ll].lap==true) return true;//主猪与任何类反猪是敌人
    if(pigg[ll].blsf==0) return false;//ll没暴身份
    if(pigg[kk].sf!=3&&pigg[ll].blsf==3) return true;//忠猪和反猪 身份不符是敌人
    if(pigg[kk].sf==3&&pigg[ll].blsf!=3) return true;
    return false;
}
bool cst_gs2(long long kk,long long ll){//真友关系
    if(pigg[ll].blsf==0) return false;
    if(pigg[kk].sf!=3&&pigg[ll].blsf!=3) return true;
    if(pigg[kk].sf==3&&pigg[ll].blsf==3) return true;
    return false;   
}
bool cst_j(long long kk,long long ll,long long la){//无懈可击
    long long to=kk;//轮流开始出无懈可击
    while(1){
        if((la==0&&cst_gs2(to,ll))||(la!=0&&cst_gs1(to,la))){//如你和锦囊牌承受者是朋友或和上一张无懈可击发出者是敌人 就用无懈可击 la值确定是哪种情况
            if(cst_zhao(ll,'J')){//如有无懈可击就出
                if(la==0&&cst_gs2(to,ll)) cst_gs3(to,ll);
                if(la!=0&&cst_gs1(to,la)) cst_gs4(to,la);//朋友和敌人关系更新 这是献殷勤或表敌意行为
                if(!cst_j(pigg[to].h,ll,to))
                    return true;//如没被其他无懈可击抵消 那这张无懈可击就有效
            }
        }
        to=pigg[to].h;
        if(to==kk) return false;//一轮之后退出
    }
}
void cst_k(long long kk,long long ll){//杀 闪
    cst_gs4(kk,ll);//表敌意行为
    bool pp=cst_zhao(ll,'D');//去ll牌里找闪
    if(pp==false)
        cst_sh(kk,ll);//找不到扣血
}
void cst_f(long long kk,long long ll){//决斗
    if(pigg[kk].sf==1&&pigg[ll].sf==2){//如是主猪对忠猪下手 忠猪不还手
        cst_sh(kk,ll);return;
    }
    while(1){
        bool to1=cst_zhao(ll,'K');//轮流在两猪牌里寻找杀 找不到就扣
        if(!to1){
            cst_sh(kk,ll);return;
        }
        bool to2=cst_zhao(ll,'K');
        if(!to2){
            cst_sh(ll,kk);return;//如是自己出牌害自己 需把两猪攻击关系调换 
        }
    }
}
void cst_n(long long kk,long long ll){//南猪入侵
    while(1){
        if(js) return;//要实时确认游戏是否结束
        if(!cst_j(kk,ll,0)){//没有被无懈可击挡住
            bool to=cst_zhao(ll,'K');//在牌中找杀
            if(!to){
                if(pigg[ll].sf==1&&pigg[kk].blsf==0){
                    pigg[kk].lap=true;//如是忠猪误伤主猪 且忠猪没暴露身份 视为类反猪
                }
                cst_sh(kk,ll);//扣血
            }
        }
        ll=pigg[ll].h;  
        if(ll==kk) return;//一次轮完退出
    }
}
void cst_w(long long kk,long long ll){//万箭齐发
    while(1){
        if(js) return;
        if(!cst_j(kk,ll,0)){
            bool to=cst_zhao(ll,'D');
            if(!to){
                if(pigg[ll].sf==1&&pigg[kk].blsf==0)
                    pigg[kk].lap=true;
                cst_sh(kk,ll);
            }
        }
        ll=pigg[ll].h;  
        if(ll==kk) return;
    }
}
void cst_yx(){
    while(true){//游戏一直运行    
        for(int i=1;i<=n;i++){
            if(js) return;//实时确定游戏结束
            if(pigg[i].hp<=0) continue;//猪死直接跳过
            cst_mo(i);
            cst_mo(i);//摸牌
            bool yk=true;//表示这头猪是否出过杀
            for(int k=1;k<=pigg[i].p;k++){
                if(pigg[i].ca[k]=='X') continue;//空牌 跳过
                if(js) return;
                switch(pigg[i].ca[k]){
                    case 'P':{
                        if(pigg[i].hp<4){//能吃桃就吃
                            pigg[i].ca[k]='X';
                            pigg[i].hp++;
                        }
                        break;
                    }
                    case 'K':{
                        if(yk&&cst_gs1(i,pigg[i].h)){//后面一只猪是敌人
                            pigg[i].ca[k]='X';
                            cst_k(i,pigg[i].h);
                            if(!pigg[i].zb)
                                yk=false;//没有连弩就不能再出杀
                            k=0;//从头再来 因为整个场面可能改变
                        }
                        break;  
                    }
                    case 'F':{//决斗
                        if(pigg[i].sf==3){//反猪 目标是主猪
                            pigg[i].ca[k]='X';
                            cst_gs4(i,1);//主猪表敌意
                            if(cst_j(i,1,0)) break;//被无懈可击挡住就退出
                            cst_f(i,1);
                            k=0;
                        }else{
                            long long to=pigg[i].h;//逆时针循环找最近敌对猪
                            while(true){
                                if(cst_gs1(i,to)){
                                    pigg[i].ca[k]='X';
                                    cst_gs4(i,to);
                                    if(cst_j(i,to,0)) break;
                                    cst_f(i,to);
                                    k=0;
                                  break;
                                }
                                to=pigg[to].h;
                                if(to==i) break;//转完就退出
                            }
                        }
                        break;
                    }
                    case 'N':{//南猪入侵 万箭齐发
                        pigg[i].ca[k]='X';
                        cst_n(i,pigg[i].h);
                        k=0;
                        break;
                    }
                    case 'W':{
                        pigg[i].ca[k]='X';
                        cst_w(i,pigg[i].h);
                        k=0;
                        break;
                    }
                    case 'Z':{//猪哥连弩
                        pigg[i].ca[k]='X';
                        pigg[i].lap=true;
                        yk=true;
                        k=0;
                        break;
                    }
                }
                while(pigg[i].ca[pigg[i].p]=='X') pigg[i].p--;//优化 清掉最后没有的牌
            }
        }
    }
}
int main(){
    n=read();
    mm=read();
    for(int i=1;i<y;i++){
        for(int k=1;k<hh;k++)
            pigg[i].ca[k]='X';//表示这位置为空位
        pigg[i].hp=4;//初始生命为4
    }
    for(int i=1;i<=n;++i){
        char ppp[10],e[10];
        scanf("%s",ppp);
        for(int k=1;k<=4;k++){
            scanf("%s",e);
            pigg[i].ca[k]=e[0];//读入牌
        }
        pigg[i].p=4;
        if(ppp[0]=='M'){
            pigg[i].sf=1;
            pigg[i].blsf=1;//主猪身份 开始就暴露
        }
        else if(ppp[0]=='Z') pigg[i].sf=2;
        else{
            pigg[i].sf=3;APs++;//反猪++
        }
        pigg[i].h=i+1;
        pigg[i].q=i-1;
    }
    pigg[n].h=1;//前驱后继 构成整个环
    pigg[1].q=n;
    for(int i=1;i<=mm;i++){
        char f[10];
        scanf("%s",f);
        zgs[i]=f[0];//牌库的牌
    }
    now=1;//指针指向牌库的第一张牌
    cst_yx();//运行游戏
    if(pigg[1].hp<=0) printf("FP\n");
    else printf("MP\n");//输出获胜者
    for(int i=1;i<=n;i++){//输出每人牌
        if(pigg[i].hp<=0) printf("DEAD\n");
        else
            cst_dy(i);
    }
    return 0;
}
/*
    主猪 MP 
    忠猪 ZP
    反猪 AP
    满满的套路 
    1 桃濒死时吃完记得回血,不要磕完桃还是零血状态
    2 用牌之前就要标记好不能再用了
    3 主猪弃牌要弃装备(猪哥连弩)
    4 对于锦囊牌先用懈再判定,因为出锦囊的猪是有可能无懈掉这个锦囊的
    5 有猪死亡的时候要重新更新第一目标
    6 出决斗的猪可能死在自己回合里,这时候立即终止它的出牌阶段
*/
2022/3/25 18:19
加载中...