猪国杀爆肝录

· · 个人记录

建立 《猪国杀爆肝录》,开始爆肝( 基本代码: ```cpp #include<bits/stdc++.h> using namespace std; int n,m; string a[15]; char pai[15][2005],pd[2005];//pd[]为牌堆 int l[15],r[15];//用char数组pai来代替queue,其中l[],r[]表示左右端点 int main(){ cin>>n>>m; for(int i=1;i<=n;i++) cin>>a[i]>>pai[i][0]>>pai[i][1]>>pai[i][2]>>pai[i][3]; for(int i=1;i<=m;i++) cin>>pd[i]; return 0; } ``` $2023$ 年 $9$ 月 $4$ 日 $21:00$: 由于时间原因停肝,已完成主猪的基本牌出牌方案(不一定对,之后可能改),并完善了一些变量。 ```cpp #include<bits/stdc++.h> using namespace std; int n,m,q=1,xue[15];//q表示当前牌堆已发至第几张牌,xue[]表示当前角色血量 string a[15],g[15];//g[]表示目前该角色标明的身份 bool dead[15];//该猪是否死亡 char pai[15][2005],pd[2005];//pd[]为牌堆 int l[15],r[15];//用char数组pai来代替queue,其中l[],r[]表示左右端点 int check(){//判断是否结束且胜者的函数 int flag=1; for(int i=1;i<=n;i++) if(a[i]=="FP" && !dead[i]){//该猪是反猪且没有死亡 flag=0;//则主猪、忠猪没有胜利 break; } if(flag) return flag;//已结束且主猪、忠猪胜利了 if(dead[1]) return 2;//主猪死亡,反猪胜利 return 0; } void kouxue(int idx){ xue[idx]--; if(xue[idx]==0){ for(int i=l[idx];i<=r[idx];i++){ if(pai[idx][i]=='P'){ for(int j=i-1;j>=l[idx];j--) pai[idx][j+1]=pai[idx][j]; l[idx]++; xue[idx]++; return ; } } dead[idx]=true; } } void shan(int idx){ for(int i=l[idx];i<=r[idx];i++){ if(pai[idx][i]=='D'){ for(int j=i-1;j>=l[idx];j--) pai[idx][j+1]=pai[idx][j]; l[idx]++; return ; } } kouxue(idx);//扣血 } void sha(int idx){ int f1=0,f2=0; for(int i=2;i<=n;i++) if(!dead[i]){ f1=i; break; } for(int i=n;i>=2;i--) if(!dead[i]){ f2=i; break; } if(g[f1]=="LFP"){//是类反猪 while(!dead[f1] && pai[idx][l[idx]]=='K'){ l[idx]++; shan(f1); } } if(f1!=f2 && g[f2]=="LFP"){//是类反猪,注意不能重合 while(!dead[f2] && pai[idx][l[idx]]=='K'){ l[idx]++; shan(f1); } } } int main(){ cin>>n>>m; g[1]="MP"; for(int i=1;i<=n;i++){ cin>>a[i]>>pai[i][0]>>pai[i][1]>>pai[i][2]>>pai[i][3]; l[i]=1;//左端点置为1 r[i]=4;//右端点置为4 xue[i]=4; } for(int i=1;i<=m;i++) cin>>pd[i]; while(!check()){ for(int i=1;i<=n;i++){ pai[i][r[i]++]=pd[q++];//摸牌阶段 if(q!=m) pai[i][r[i]++]=pd[q++];//摸牌阶段 if(a[i]=="MP"){ while(true){ if(pai[i][l[i]]=='P') if(xue[i]!=4){ xue[i]++; l[i]++; }else break; else if(pai[i][l[i]]=='D') break; else if(pai[i][l[i]]=='K') sha(i); } } } } return 0; } ``` $2023$ 年 $9$ 月 $5$ 日 $13:33$: 成功写出了万箭齐发、南猪入侵及主猪视角下的杀、决斗,暂时没考虑无懈可击的情况并再次完善变量。 ```cpp #include<bits/stdc++.h> using namespace std; int wuqi[15];//可出杀的数量 int n,m,q=1,xue[15];//q表示当前牌堆已发至第几张牌,xue[]表示当前角色血量 string a[15],g[15];//g[]表示目前该角色标明的身份 bool dead[15];//该猪是否死亡 char pai[15][2005],pd[2005];//pd[]为牌堆 int l[15],r[15];//用char数组pai来代替queue,其中l[],r[]表示左右端点 int check(){//判断是否结束且胜者的函数 int flag=1; for(int i=1;i<=n;i++) if(a[i]=="FP" && !dead[i]){//该猪是反猪且没有死亡 flag=0;//则主猪、忠猪没有胜利 break; } if(flag) return flag;//已结束且主猪、忠猪胜利了 if(dead[1]) return 2;//主猪死亡,反猪胜利 return 0; } void kouxue(int idx){ xue[idx]--; if(xue[idx]==0){ for(int i=l[idx];i<=r[idx];i++){ if(pai[idx][i]=='P'){ for(int j=i-1;j>=l[idx];j--) pai[idx][j+1]=pai[idx][j]; l[idx]++; xue[idx]++; return ; } } dead[idx]=true; } } void shan(int idx){ for(int i=l[idx];i<=r[idx];i++){ if(pai[idx][i]=='D'){ for(int j=i-1;j>=l[idx];j--) pai[idx][j+1]=pai[idx][j]; l[idx]++; return ; } } kouxue(idx);//扣血 } void shaa(int idx){//同shan() for(int i=l[idx];i<=r[idx];i++){ if(pai[idx][i]=='K'){ for(int j=i-1;j>=l[idx];j--) pai[idx][j+1]=pai[idx][j]; l[idx]++; return ; } } kouxue(idx);//扣血 } void sha(int idx){ int f1=0,f2=0; for(int i=idx+1;i<=n;i++) if(!dead[i]){ f1=i; break; } if(!f1) for(int i=1;i<idx;i++) if(!dead[i]){ f1=i; break; } for(int i=idx-1;i>=1;i--) if(!dead[i]){ f2=i; break; } for(int i=n;i>=idx+1;i--) if(!dead[i]){ f1=i; break; } if(a[idx]=="MP"){ if(g[f1]=="LFP"){//类反猪 while(!dead[f1] && pai[idx][l[idx]]=='K' && wuqi[idx]>0){//一直杀这只猪 l[idx]++; shan(f1); } } if(f1!=f2 && g[f2]=="LFP"){//同上 while(!dead[f2] && pai[idx][l[idx]]=='K' && wuqi[idx]>0){//同上 l[idx]++; shan(f2); } } } } void duisha(int i,int j){//到i出杀 int q=xue[i]; shaa(i);//出一张杀 if(q==xue[i]) duisha(j,i);//对调,到j出杀 } void juedou(int idx){ for(int i=1;i<=n;i++){ if(!dead[i] && i!=idx){ if(a[idx]=="MP" && g[i]=="LFP"){ while(pai[idx][l[idx]]=='F'){ duisha(i,idx);//开始决斗 l[idx]++; } } } } } void wanjianqifa(int idx){ while(pai[idx][l[idx]]=='W'){ l[idx]++; for(int i=1;i<=n;i++){ if(!dead[i] && i!=idx) shan(i);//出一张闪 } } } void nanzhuruqin(int idx){ while(pai[idx][l[idx]]=='N'){ l[idx]++; for(int i=1;i<=n;i++){ if(!dead[i] && i!=idx) shaa(i);//出一张杀 } } } int main(){ cin>>n>>m; g[1]="MP"; for(int i=1;i<=n;i++){ cin>>a[i]>>pai[i][0]>>pai[i][1]>>pai[i][2]>>pai[i][3]; l[i]=1;//左端点置为1 r[i]=4;//右端点置为4 xue[i]=4; } for(int i=1;i<=m;i++) cin>>pd[i]; while(!check()){ for(int i=1;i<=n;i++){ if(wuqi[i]==0)//重置,注意这里不需重置有武器的情况 wuqi[i]=1; pai[i][r[i]++]=pd[q++];//摸牌阶段 if(q!=m) pai[i][r[i]++]=pd[q++];//摸牌阶段 while(true){ if(pai[i][l[i]]=='P') if(xue[i]!=4){ xue[i]++; l[i]++; }else break; else if(pai[i][l[i]]=='D') break; else if(pai[i][l[i]]=='K' && wuqi[i]>0) sha(i); else if(pai[i][l[i]]=='F') juedou(i); else if(pai[i][l[i]]=='W') wanjianqifa(i); else if(pai[i][l[i]]=='N') nanzhuruqin(i); else if(pai[i][l[i]]=='J') break; else if(pai[i][l[i]]=='Z') wuqi[i]=142857;//相当于无限出杀 else//防止有一堆杀但是只能出一张的情况 break; } } } return 0; } ``` $2023$ 年 $9$ 月 $6$ 日 $19:19$: 完成了忠猪角度下的杀,并完成一部分反猪角度下的杀,成功的模拟了杀死反猪和主猪杀死忠猪的情况,暂时未对决斗的【发起者为主猪,接收者为忠猪】做出模拟。 ```cpp #include<bits/stdc++.h> using namespace std; int wuqi[15];//可出杀的数量 int n,m,q=1,xue[15];//q表示当前牌堆已发至第几张牌,xue[]表示当前角色血量 string a[15],g[15];//g[]表示目前该角色标明的身份 bool dead[15];//该猪是否死亡 char pai[15][2005],pd[2005];//pd[]为牌堆 int l[15],r[15];//用char数组pai来代替queue,其中l[],r[]表示左右端点 int check(){//判断是否结束且胜者的函数 int flag=1; for(int i=1;i<=n;i++) if(a[i]=="FP" && !dead[i]){//该猪是反猪且没有死亡 flag=0;//则主猪、忠猪没有胜利 break; } if(flag) return flag;//已结束且主猪、忠猪胜利了 if(dead[1]) return 2;//主猪死亡,反猪胜利 return 0; } void kouxue(int i,int idx){ xue[idx]--; if(xue[idx]==0){ for(int i=l[idx];i<=r[idx];i++){ if(pai[idx][i]=='P'){ for(int j=i-1;j>=l[idx];j--) pai[idx][j+1]=pai[idx][j]; l[idx]++; xue[idx]++; return ; } } dead[idx]=true; } if(dead[idx]==true){ if(a[idx]=="FP"){//杀死反猪,摸三张牌 pai[i][r[i]++]=q++; if(q!=m) pai[i][r[i]++]=q++; if(q!=m) pai[i][r[i]++]=q++; } if(a[idx]=="ZP" && a[i]=="MP"){//主猪杀死了忠猪 l[i]=r[i]=1; pai[i][l[i]]='1';//模拟清空所有牌 } } if(a[idx]=="MP" && g[i]!="ZP") g[i]="LFP"; } void shan(int i,int idx){ for(int i=l[idx];i<=r[idx];i++){ if(pai[idx][i]=='D'){ for(int j=i-1;j>=l[idx];j--) pai[idx][j+1]=pai[idx][j]; l[idx]++; return ; } } kouxue(i,idx);//扣血 } void shaa(int i,int idx){//同shan() for(int i=l[idx];i<=r[idx];i++){ if(pai[idx][i]=='K'){ for(int j=i-1;j>=l[idx];j--) pai[idx][j+1]=pai[idx][j]; l[idx]++; return ; } } kouxue(i,idx);//扣血 } void sha(int idx){ int f1=0,f2=0; for(int i=idx+1;i<=n;i++) if(!dead[i]){ f1=i; break; } if(!f1) for(int i=1;i<idx;i++) if(!dead[i]){ f1=i; break; } for(int i=idx-1;i>=1;i--) if(!dead[i]){ f2=i; break; } for(int i=n;i>=idx+1;i--) if(!dead[i]){ f1=i; break; } if(a[idx]=="MP"){ if(g[f1]=="LFP" || g[f1]=="FP"){//类反猪或反猪 while(!dead[f1] && pai[idx][l[idx]]=='K' && wuqi[idx]>0){//一直杀这只猪 l[idx]++; shan(idx,f1); } } if(f1!=f2 && (g[f2]=="LFP" || g[f2]=="FP")){//同上 while(!dead[f2] && pai[idx][l[idx]]=='K' && wuqi[idx]>0){//同上 l[idx]++; shan(idx,f2); } } } if(a[idx]=="ZP"){//同主猪 if(g[f1]=="LFP" || g[f1]=="FP"){//类反猪或反猪 while(!dead[f1] && pai[idx][l[idx]]=='K' && wuqi[idx]>0){//一直杀这只猪 l[idx]++; shan(idx,f1); } } if(f1!=f2 && (g[f2]=="LFP" || g[f2]=="FP")){//同上 while(!dead[f2] && pai[idx][l[idx]]=='K' && wuqi[idx]>0){//同上 l[idx]++; shan(idx,f2); } } } if(a[idx]=="FP"){//先杀主猪,再杀忠猪 if(a[f1]=="MP"){//还没完,还有f2是忠猪的情况 while(!dead[f1] && pai[idx][l[idx]]=='K' && wuqi[idx]>0){//一直杀这只猪 l[idx]++; shan(idx,f1); } } if(a[f2]=="MP"){//还没完,还有f1是忠猪的情况 while(!dead[f2] && pai[idx][l[idx]]=='K' && wuqi[idx]>0){ l[idx]++; shan(idx,f2); } } } } void duisha(int i,int j){//到i出杀 int q=xue[i]; shaa(j,i);//出一张杀 if(q==xue[i]) duisha(j,i);//对调,到j出杀 } void juedou(int idx){ for(int i=1;i<=n;i++){ if(!dead[i] && i!=idx){ if(a[idx]=="MP" && g[i]=="LFP"){ while(pai[idx][l[idx]]=='F'){ duisha(i,idx);//开始决斗 l[idx]++; } } } } } void wanjianqifa(int idx){ while(pai[idx][l[idx]]=='W'){ l[idx]++; for(int i=1;i<=n;i++){ if(!dead[i] && i!=idx) shan(idx,i);//出一张闪 } } } void nanzhuruqin(int idx){ while(pai[idx][l[idx]]=='N'){ l[idx]++; for(int i=1;i<=n;i++){ if(!dead[i] && i!=idx) shaa(idx,i);//出一张杀 } } } int main(){ cin>>n>>m; g[1]="MP"; for(int i=1;i<=n;i++){ cin>>a[i]>>pai[i][0]>>pai[i][1]>>pai[i][2]>>pai[i][3]; l[i]=1;//左端点置为1 r[i]=4;//右端点置为4 xue[i]=4; } for(int i=1;i<=m;i++) cin>>pd[i]; while(!check()){ for(int i=1;i<=n;i++){ if(wuqi[i]==0)//重置,注意这里不需重置有武器的情况 wuqi[i]=1; pai[i][r[i]++]=pd[q++];//摸牌阶段 if(q!=m) pai[i][r[i]++]=pd[q++];//摸牌阶段 while(true){ if(pai[i][l[i]]=='P') if(xue[i]!=4){ xue[i]++; l[i]++; }else break; else if(pai[i][l[i]]=='D') break; else if(pai[i][l[i]]=='K' && wuqi[i]>0) sha(i); else if(pai[i][l[i]]=='F') juedou(i); else if(pai[i][l[i]]=='W') wanjianqifa(i); else if(pai[i][l[i]]=='N') nanzhuruqin(i); else if(pai[i][l[i]]=='J') break; else if(pai[i][l[i]]=='Z') wuqi[i]=142857;//相当于无限出杀 else//防止有一堆杀但是只能出一张的情况或手里没牌 break; } } } return 0; } ``` $2023$ 年 $9$ 月 $7$ 日 $13:26$: 成功的做出献殷勤及相对的表敌意,基本全部完成,但是 CE 了,先把代码放在这里. ```cpp /* #include<bits/stdc++.h> using namespace std; int main(){ srand(time(NULL)); cout<<rand()%36+1<<"\n"; int k=5; cout<<"做"<<rand()%k+1<<"题"; return 0; } */ #include<bits/stdc++.h> using namespace std; int wuqi[15];//可出杀的数量 int n,m,q=1,xue[15];//q表示当前牌堆已发至第几张牌,xue[]表示当前角色血量 string a[15],g[15];//g[]表示目前该角色标明的身份 bool dead[15];//该猪是否死亡 char pai[15][2005],pd[2005];//pd[]为牌堆 int l[15],r[15];//用char数组pai来代替queue,其中l[],r[]表示左右端点 bool wuxiekeji(int idx){//是否能出一张无懈可击 for(int i=l[idx];i<=r[idx];i++){ if(pai[idx][i]=='J'){ for(int j=i-1;j>=l[idx];j--) pai[idx][j+1]=pai[idx][j]; l[idx]++; g[idx]=a[idx];//重点!表敌意和献殷勤实际上就是跳忠或跳反 return true; } } return false; } bool biaodiyi(int idx){//献殷勤的猪是idx for(int i=1;i<=n;i++){ if(g[idx]="FP" && a[i]=="ZP" || g[idx]=="ZP" && a[i]=="FP" || g[idx]=="FP" && a[i]=="MP" || a[idx]=="MP" && g[i]=="FP"){//注意这里不存在类反猪,因为类反猪在献殷勤是一定被主猪重新认识了 if(wuxiekeji(i)){ g[i]=a[i];//同wuxiekeji()里的这句 return true; } } } return false;//失败了 }//注意这里的表敌意单指抵消献殷勤 bool xianyinqin(int idx){//是否成功献殷勤 for(int i=1;i<=n;i++){ if((g[idx]="FP" && a[i]=="FP") || (g[idx]=="ZP" && a[i]=="ZP") || (g[idx]=="ZP" && a[i]=="MP") || (a[idx]=="MP" && g[i]=="ZP")){ bool q,p; while(q=wuxiekeji(i) && b=biaodiyi(i)){//出了但是被挡下了 g[i]=a[i];//同wuxiekeji()里的这句 } if(q && !p){//出了但是没被挡下 g[i]=a[i];//同上 return true; } } } return false;//献殷勤失败 } int check(){//判断是否结束且目前胜者的函数 int flag=1; for(int i=1;i<=n;i++) if(a[i]=="FP" && !dead[i]){//该猪是反猪且没有死亡 flag=0;//则主猪、忠猪没有胜利 break; } if(flag) return flag;//已结束且主猪、忠猪胜利了 if(dead[1]) return 2;//主猪死亡,反猪胜利 return 0; } void kouxue(int i,int idx){//扣血函数,i为伤害来源 xue[idx]--; if(xue[idx]==0){ for(int i=l[idx];i<=r[idx];i++){//是否能吃桃补救 if(pai[idx][i]=='P'){ for(int j=i-1;j>=l[idx];j--) pai[idx][j+1]=pai[idx][j]; l[idx]++; xue[idx]++;//补救成功了 return ; } } dead[idx]=true;//失败了,则该猪死亡 } if(dead[idx]==true){ if(a[idx]=="FP"){//杀死反猪,摸三张牌 pai[i][r[i]++]=q++; if(q!=m) pai[i][r[i]++]=q++; if(q!=m) pai[i][r[i]++]=q++; } if(a[idx]=="ZP" && a[i]=="MP"){//主猪杀死了忠猪 l[i]=r[i]=1; pai[i][l[i]]='1';//模拟清空所有牌 } } if(a[idx]=="MP" && g[i]!="ZP")//还没跳忠的猪攻击了主猪 g[i]="LFP"; } void shan(int i,int idx){//出一张闪 for(int i=l[idx];i<=r[idx];i++){ if(pai[idx][i]=='D'){ for(int j=i-1;j>=l[idx];j--) pai[idx][j+1]=pai[idx][j]; l[idx]++; return ; } } kouxue(i,idx);//扣血 } void shaa(int i,int idx){//同shan() for(int i=l[idx];i<=r[idx];i++){ if(pai[idx][i]=='K'){ for(int j=i-1;j>=l[idx];j--) pai[idx][j+1]=pai[idx][j]; l[idx]++; return ; } } kouxue(i,idx);//扣血 } void sha(int idx){ int F=0,qqq=0; for(int i=2;i<=n;i++)//找离主猪最近的向左可以攻击到主猪的猪 if(!dead[i]){ qqq=i; break; } for(int i=idx+1;i<=n;i++) if(!dead[i]){ F=i; break; } if(!F) for(int i=1;i<idx;i++) if(!dead[i]){ F=i; break; } if(a[idx]=="MP"){ if(g[F]=="LFP" || g[F]=="FP"){//类反猪或反猪 while(!dead[F] && pai[idx][l[idx]]=='K' && wuqi[idx]>0){//一直杀这只猪 l[idx]++; shan(idx,F); } } } if(a[idx]=="ZP"){//同主猪 if(g[F]=="LFP" || g[F]=="FP"){//类反猪或反猪 while(!dead[F] && pai[idx][l[idx]]=='K' && wuqi[idx]>0){//一直杀这只猪 l[idx]++; shan(idx,F); } g[F]="ZP";//跳忠 } } if(a[idx]=="FP"){//杀忠猪或主猪 if(idx==qqq){//可以向左攻击到主猪 while(!dead[1] && pai[idx][l[idx]]=='K' && wuqi[idx]>0){//一直杀主猪 l[idx]++; shan(idx,1); } g[F]="FP";//跳反 return ; } if(a[F]=="MP" || a[F]=="ZP"){//忠猪或主猪 while(!dead[F] && pai[idx][l[idx]]=='K' && wuqi[idx]>0){//一直杀这只猪 l[idx]++; shan(idx,F); } g[F]="FP";//跳反 } } } void duisha(int i,int j){//到i出杀 if(a[i]=="ZP" && a[j]=="MP"){//若发起者为主猪且接受者为忠猪,则忠猪直接扣血 kouxue[i]; return ; } int q=xue[i]; shaa(j,i);//出一张杀 if(q==xue[i]) duisha(j,i);//对调,到j出杀 } void juedou(int idx){ if(a[idx]=="FP"){//注意反猪需要单独拎出来 duisha(1,idx);//无条件攻击主猪 g[idx]="FP";//跳反 return ; } for(int i=1;i<=n;i++){ if(!dead[i] && i!=idx){ if(a[idx]=="MP" && (g[i]=="LFP" || g[i]=="FP")){//攻击反猪或类反猪 while(pai[idx][l[idx]]=='F' && !xianyinqin(i)){//没人给他献殷勤 duisha(i,idx);//开始决斗 l[idx]++; } break;//只对其表敌意 } if(a[idx]=="ZP" && (g[i]=="LFP" || g[i]=="FP")){//同主猪 while(pai[idx][l[idx]]=='F' && !xianyinqin(i)){//同上 duisha(i,idx);//开始决斗 l[idx]++; } g[idx]="ZP";//跳忠 break;//只对其表敌意 } } } } void wanjianqifa(int idx){ while(pai[idx][l[idx]]=='W'){ l[idx]++; for(int i=1;i<=n;i++){ if(!dead[i] && i!=idx && !xianyinqin(i))//没人给他献殷勤 shan(idx,i);//出一张闪 } } } void nanzhuruqin(int idx){ while(pai[idx][l[idx]]=='N'){ l[idx]++; for(int i=1;i<=n;i++){ if(!dead[i] && i!=idx && !xianyinqin(i))//没人给他献殷勤 shaa(idx,i);//出一张杀 } } } int main(){ cin>>n>>m; g[1]="MP"; for(int i=1;i<=n;i++){ cin>>a[i]>>pai[i][0]>>pai[i][1]>>pai[i][2]>>pai[i][3]; l[i]=1;//左端点置为1 r[i]=4;//右端点置为4 xue[i]=4; } for(int i=1;i<=m;i++) cin>>pd[i]; while(!check()){ for(int i=1;i<=n;i++){ if(wuqi[i]==0)//重置,注意这里不需重置有武器的情况 wuqi[i]=1; pai[i][r[i]++]=pd[q++];//摸牌阶段 if(q!=m) pai[i][r[i]++]=pd[q++];//摸牌阶段 while(true){ if(pai[i][l[i]]=='P') if(xue[i]!=4){ xue[i]++; l[i]++; }else break; else if(pai[i][l[i]]=='D') break; else if(pai[i][l[i]]=='K' && wuqi[i]>0) sha(i); else if(pai[i][l[i]]=='F') juedou(i); else if(pai[i][l[i]]=='W') wanjianqifa(i); else if(pai[i][l[i]]=='N') nanzhuruqin(i); else if(pai[i][l[i]]=='J') break; else if(pai[i][l[i]]=='Z') wuqi[i]=142857;//相当于无限出杀 else//防止有一堆杀但是只能出一张的情况或手里没牌 break; } } } if(check()==1) cout<<"MP\n"; else cout<<"FP\n"; for(int i=1;i<=n;i++){ if(dead[i]) cout<<"DEAD\n"; else{ for(int j=l[i];j<=r[i];j++) cout<<pai[i][j]<<' '; cout<<"\n"; } } return 0; } ``` 同一天 $13:32$: 成功优化 CE,但是 T 了。 ```cpp #include<bits/stdc++.h> using namespace std; int wuqi[15];//可出杀的数量 int n,m,qq=1,xue[15];//q表示当前牌堆已发至第几张牌,xue[]表示当前角色血量 bool q,p; string a[15],g[15];//g[]表示目前该角色标明的身份 bool dead[15];//该猪是否死亡 char pai[15][2005],pd[2005];//pd[]为牌堆 int l[15],r[15];//用char数组pai来代替queue,其中l[],r[]表示左右端点 bool wuxiekeji(int idx){//是否能出一张无懈可击 for(int i=l[idx];i<=r[idx];i++){ if(pai[idx][i]=='J'){ for(int j=i-1;j>=l[idx];j--) pai[idx][j+1]=pai[idx][j]; l[idx]++; g[idx]=a[idx];//重点!表敌意和献殷勤实际上就是跳忠或跳反 return qq=true; } } return qq=false; } bool biaodiyi(int idx){//献殷勤的猪是idx for(int i=1;i<=n;i++){ if(g[idx]=="FP" && a[i]=="ZP" || g[idx]=="ZP" && a[i]=="FP" || g[idx]=="FP" && a[i]=="MP" || a[idx]=="MP" && g[i]=="FP"){//注意这里不存在类反猪,因为类反猪在献殷勤是一定被主猪重新认识了 if(wuxiekeji(i)){ g[i]=a[i];//同wuxiekeji()里的这句 return p=true; } } } return p=false;//失败了 }//注意这里的表敌意单指抵消献殷勤 bool xianyinqin(int idx){//是否成功献殷勤 for(int i=1;i<=n;i++){ if((g[idx]=="FP" && a[i]=="FP") || (g[idx]=="ZP" && a[i]=="ZP") || (g[idx]=="ZP" && a[i]=="MP") || (a[idx]=="MP" && g[i]=="ZP")){ qq=p=false; while(wuxiekeji(i) && biaodiyi(i)){//出了但是被挡下了 g[i]=a[i];//同wuxiekeji()里的这句 } if(qq && !p){//出了但是没被挡下 g[i]=a[i];//同上 return true; } } } return false;//献殷勤失败 } int check(){//判断是否结束且目前胜者的函数 int flag=1; for(int i=1;i<=n;i++) if(a[i]=="FP" && !dead[i]){//该猪是反猪且没有死亡 flag=0;//则主猪、忠猪没有胜利 break; } if(flag) return flag;//已结束且主猪、忠猪胜利了 if(dead[1]) return 2;//主猪死亡,反猪胜利 return 0; } void kouxue(int i,int idx){//扣血函数,i为伤害来源 xue[idx]--; if(xue[idx]==0){ for(int i=l[idx];i<=r[idx];i++){//是否能吃桃补救 if(pai[idx][i]=='P'){ for(int j=i-1;j>=l[idx];j--) pai[idx][j+1]=pai[idx][j]; l[idx]++; xue[idx]++;//补救成功了 return ; } } dead[idx]=true;//失败了,则该猪死亡 } if(dead[idx]==true){ if(a[idx]=="FP"){//杀死反猪,摸三张牌 pai[i][r[i]++]=q++; if(q!=m) pai[i][r[i]++]=q++; if(q!=m) pai[i][r[i]++]=q++; } if(a[idx]=="ZP" && a[i]=="MP"){//主猪杀死了忠猪 l[i]=r[i]=1; pai[i][l[i]]='1';//模拟清空所有牌 } } if(a[idx]=="MP" && g[i]!="ZP")//还没跳忠的猪攻击了主猪 g[i]="LFP"; } void shan(int i,int idx){//出一张闪 for(int i=l[idx];i<=r[idx];i++){ if(pai[idx][i]=='D'){ for(int j=i-1;j>=l[idx];j--) pai[idx][j+1]=pai[idx][j]; l[idx]++; return ; } } kouxue(i,idx);//扣血 } void shaa(int i,int idx){//同shan() for(int i=l[idx];i<=r[idx];i++){ if(pai[idx][i]=='K'){ for(int j=i-1;j>=l[idx];j--) pai[idx][j+1]=pai[idx][j]; l[idx]++; return ; } } kouxue(i,idx);//扣血 } void sha(int idx){ int F=0,qqq=0; for(int i=2;i<=n;i++)//找离主猪最近的向左可以攻击到主猪的猪 if(!dead[i]){ qqq=i; break; } for(int i=idx+1;i<=n;i++) if(!dead[i]){ F=i; break; } if(!F) for(int i=1;i<idx;i++) if(!dead[i]){ F=i; break; } if(a[idx]=="MP"){ if(g[F]=="LFP" || g[F]=="FP"){//类反猪或反猪 while(!dead[F] && pai[idx][l[idx]]=='K' && wuqi[idx]>0){//一直杀这只猪 l[idx]++; shan(idx,F); } } } if(a[idx]=="ZP"){//同主猪 if(g[F]=="LFP" || g[F]=="FP"){//类反猪或反猪 while(!dead[F] && pai[idx][l[idx]]=='K' && wuqi[idx]>0){//一直杀这只猪 l[idx]++; shan(idx,F); } g[F]="ZP";//跳忠 } } if(a[idx]=="FP"){//杀忠猪或主猪 if(idx==qqq){//可以向左攻击到主猪 while(!dead[1] && pai[idx][l[idx]]=='K' && wuqi[idx]>0){//一直杀主猪 l[idx]++; shan(idx,1); } g[F]="FP";//跳反 return ; } if(a[F]=="MP" || a[F]=="ZP"){//忠猪或主猪 while(!dead[F] && pai[idx][l[idx]]=='K' && wuqi[idx]>0){//一直杀这只猪 l[idx]++; shan(idx,F); } g[F]="FP";//跳反 } } } void duisha(int i,int j){//到i出杀 if(a[i]=="ZP" && a[j]=="MP"){//若发起者为主猪且接受者为忠猪,则忠猪直接扣血 kouxue(j,i); return ; } int q=xue[i]; shaa(j,i);//出一张杀 if(q==xue[i]) duisha(j,i);//对调,到j出杀 } void juedou(int idx){ if(a[idx]=="FP"){//注意反猪需要单独拎出来 duisha(1,idx);//无条件攻击主猪 g[idx]="FP";//跳反 return ; } for(int i=1;i<=n;i++){ if(!dead[i] && i!=idx){ if(a[idx]=="MP" && (g[i]=="LFP" || g[i]=="FP")){//攻击反猪或类反猪 while(pai[idx][l[idx]]=='F' && !xianyinqin(i)){//没人给他献殷勤 duisha(i,idx);//开始决斗 l[idx]++; } break;//只对其表敌意 } if(a[idx]=="ZP" && (g[i]=="LFP" || g[i]=="FP")){//同主猪 while(pai[idx][l[idx]]=='F' && !xianyinqin(i)){//同上 duisha(i,idx);//开始决斗 l[idx]++; } g[idx]="ZP";//跳忠 break;//只对其表敌意 } } } } void wanjianqifa(int idx){ while(pai[idx][l[idx]]=='W'){ l[idx]++; for(int i=1;i<=n;i++){ if(!dead[i] && i!=idx && !xianyinqin(i))//没人给他献殷勤 shan(idx,i);//出一张闪 } } } void nanzhuruqin(int idx){ while(pai[idx][l[idx]]=='N'){ l[idx]++; for(int i=1;i<=n;i++){ if(!dead[i] && i!=idx && !xianyinqin(i))//没人给他献殷勤 shaa(idx,i);//出一张杀 } } } int main(){ cin>>n>>m; g[1]="MP"; for(int i=1;i<=n;i++){ cin>>a[i]>>pai[i][0]>>pai[i][1]>>pai[i][2]>>pai[i][3]; l[i]=1;//左端点置为1 r[i]=4;//右端点置为4 xue[i]=4; } for(int i=1;i<=m;i++) cin>>pd[i]; while(!check()){ for(int i=1;i<=n;i++){ if(wuqi[i]==0)//重置,注意这里不需重置有武器的情况 wuqi[i]=1; pai[i][r[i]++]=pd[q++];//摸牌阶段 if(q!=m) pai[i][r[i]++]=pd[q++];//摸牌阶段 while(true){ if(pai[i][l[i]]=='P') if(xue[i]!=4){ xue[i]++; l[i]++; }else break; else if(pai[i][l[i]]=='D') break; else if(pai[i][l[i]]=='K' && wuqi[i]>0) sha(i); else if(pai[i][l[i]]=='F') juedou(i); else if(pai[i][l[i]]=='W') wanjianqifa(i); else if(pai[i][l[i]]=='N') nanzhuruqin(i); else if(pai[i][l[i]]=='J') break; else if(pai[i][l[i]]=='Z') wuqi[i]=142857;//相当于无限出杀 else//防止有一堆杀但是只能出一张的情况或手里没牌 break; } } } if(check()==1) cout<<"MP\n"; else cout<<"FP\n"; for(int i=1;i<=n;i++){ if(dead[i]) cout<<"DEAD\n"; else{ for(int j=l[i];j<=r[i];j++) cout<<pai[i][j]<<' '; cout<<"\n"; } } return 0; } ```