暴力模拟。
认真读题,并将所有信息列在草稿中。对于这种大模拟。
代码里有一些必要的注释。
#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;
}
京公网安备 11010502036488号