记录编号 458293 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [SDOI 2010] 猪国杀 最终得分 100
用户昵称 GravatarHzoi_Mafia 是否通过 通过
代码语言 C++ 运行时间 0.008 s
提交时间 2017-10-10 21:33:34 内存使用 0.36 MiB
显示代码纯文本
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
char card[5005],paidui[5005],op[5];//card 所有牌 paidui 牌堆
int pre[5005],nxt[5005],cnt;//牌的链表
int top,bot,m,n;//top 牌堆顶 bot 读入时往牌堆里压
int sumf;//sumf 反贼数量
int zhugong;//主公
bool gameover;
inline char get_card(){
	if(top!=m)
		++top;
	return paidui[top];//听说没牌了要一直摸最后一张
}
inline void kill(int,int);
inline void fight(int,int);
inline void nanman(int);
inline void wanjian(int);
inline void hurt(int,int);
inline void godie(int,int);
inline bool wuxiekeji(int,bool);
struct piggy{
	int id,appear,blood,num;//id 身份 1主公 2忠臣 3反贼 appear 跳的情况 0 没跳 1 类反 2跳忠 3跳反 num 几号
	int nump,numk,numd,numf,numn,numw,numj;//各牌的数量 p 桃 k 杀 d 闪 f 决斗 n 南蛮 w 万箭 j 无懈
	bool zhuge,dead;//诸葛 死没死
	int prepig,nxtpig,head,last,now,tmp;//链表 牌的链表
	int attack;//首要攻击目标
	piggy():appear(0),blood(4),nump(0),numk(0),numd(0),numf(0),numn(0),numw(0),numj(0),head(0),last(0),now(0),attack(0){}
	inline void mopai(){//摸一张牌
		card[++cnt]=get_card();
		pre[cnt]=last;
		if(!head)head=last=cnt;
		else nxt[last]=cnt,last=cnt;//更新链表
		if(card[cnt]=='P')++nump;
		if(card[cnt]=='K')++numk;
		if(card[cnt]=='D')++numd;
		if(card[cnt]=='F')++numf;
		if(card[cnt]=='N')++numn;
		if(card[cnt]=='W')++numw;
		if(card[cnt]=='J')++numj;
	}
	inline void award(){//杀一个的奖励
		mopai(),mopai(),mopai();
	}
	inline void punish(){//杀错的惩罚
		head=last=now=nump=numk=numd=numf=numn=numw=numj=0;
		zhuge=false;
	}
	inline void mopaistage(){//摸牌阶段
		mopai(),mopai();
	}
	inline void use(int x){//打出一张牌
		if(card[x]=='P')--nump;
		if(card[x]=='K')--numk;
		if(card[x]=='D')--numd;
		if(card[x]=='F')--numf;
		if(card[x]=='N')--numn;
		if(card[x]=='W')--numw;
		if(card[x]=='J')--numj;
		if(x==head&&x==last)head=last=0;
		else
			if(x==head)
				head=nxt[x],pre[head]=0;
			else
				if(x==last)
					last=pre[x],nxt[last]=0;
				else
					pre[nxt[x]]=pre[x],nxt[pre[x]]=nxt[x];//更新链表
	}
	inline char get_nxt(){//找下一张牌
		if(!now)return 0;
		tmp=now;
		now=nxt[now];
		return card[tmp];
	}
	inline int findp(){//找桃
		now=head;
		char tp;
		while(tp=get_nxt())
			if(tp=='P')
				return tmp;
	}
	inline int findk(){//找杀
		now=head;
		char tp;
		while(tp=get_nxt())
			if(tp=='K')
				return tmp;
	}
	inline int findd(){//找闪
		now=head;
		char tp;
		while(tp=get_nxt())
			if(tp=='D')
				return tmp;
	}
	inline int findf(){//找决斗
		now=head;
		char tp;
		while(tp=get_nxt())
			if(tp=='F')
				return tmp;
	}
	inline int findn(){//找南蛮
		now=head;
		char tp;
		while(tp=get_nxt())
			if(tp=='N')
				return tmp;
	}
	inline int findw(){//找万箭
		now=head;
		char tp;
		while(tp=get_nxt())
			if(tp=='W')
				return tmp;
	}
	inline int findj(){//找无懈
		now=head;
		char tp;
		while(tp=get_nxt())
			if(tp=='J')
				return tmp;
	}
	inline bool qiup(){//尝试出桃,返回是否出成桃
		if(nump){
			use(findp());
			return true;
		}
		return false;
	}
	inline bool qiuk(){//尝试出杀
		if(numk){
			use(findk());
			return true;
		}
		return false;
	}
	inline bool qiud(){//尝试出闪
		if(numd){
			use(findd());
			return true;
		}
		return false;
	}
	inline bool qiuf(){//尝试出决斗
		if(numf){
			use(findf());
			return true;
		}
		return false;
	}
	inline bool qiun(){//尝试出南蛮
		if(numn){
			use(findn());
			return true;
		}
		return false;
	}
	inline bool qiuw(){//尝试出万箭
		if(numw){
			use(findw());
			return true;
		}
		return false;
	}
	inline bool qiuj(){//尝试出无懈
		if(numj){
			use(findj());
			return true;
		}
		return false;
	}
	inline void round(){//回合
		mopaistage();
//      cout<<"mopai is over "<<cnt<<endl;
		now=head;
		char tp;
		bool usedsha(false);
		while((tp=get_nxt())&&!gameover){
//          cout<<"now the card is "<<tp<<endl;
			if(tp=='D'||tp=='J')continue;
			if(tp=='P'){
				if(blood<4)
					++blood,use(tmp);
				continue;
			}
			if(tp=='K'){
				if(attack==nxtpig){
					if(!usedsha||zhuge){
						use(tmp);
						kill(num,attack);
						usedsha=true;
						now=head;
						if(gameover)return;
					}
				}
				continue;
			}
			if(tp=='F'){
				if(!attack)continue;
				use(tmp);
				if(id==3)fight(num,1);
				else fight(num,attack);
				now=head;
				if(gameover||dead)return;//决斗可以自杀
				continue;
			}
			if(tp=='N'){
				use(tmp);
				nanman(num);
				now=head;
				if(gameover)return;
				continue;
			}
			if(tp=='W'){
				use(tmp);
				wanjian(num);
				now=head;
				if(gameover)return;
				continue;
			}
			if(tp=='Z'){
				use(tmp);
				zhuge=true;
				now=head;//从头开始出,因为诸葛可以让前面的杀出来,前面的也是这个作用
				continue;
			}
		}
	}
	inline void print(){
		if(dead)puts("DEAD");
		else{
			while(head){
				printf("%c",card[head]);
				if(head!=last)putchar(' ');
				head=nxt[head];
			}
			puts("");
		}
	}
}a[15];
inline void cal_attack(int x){//计算攻击目标
	int y(a[x].nxtpig);
	if(a[x].id==1){
		while(y!=x){
			if(a[y].appear==1||a[y].appear==3){
				a[x].attack=y;
				return;
			}
			y=a[y].nxtpig;
		}
	}
	if(a[x].id==2){
		while(y!=x){
			if(a[y].appear==3){
				a[x].attack=y;
				return;
			}
			y=a[y].nxtpig;
		}
	}
	if(a[x].id==3){
		while(y!=x){
			if(a[y].appear==2||a[y].id==1){
				a[x].attack=y;
				return;
			}
			y=a[y].nxtpig;
		}
	}
	a[x].attack=0;
}
inline void allcal(){//所有猪计算一遍
	int x(a[zhugong].nxtpig);
	cal_attack(zhugong);
	while(x!=zhugong){
		cal_attack(x);
		x=a[x].nxtpig;
	}
}
inline void hurt(int x,int y){//x对y造成伤害
	--a[y].blood;
//  cout<<"now "<<x<<" hurt "<<y<<endl;
	if(!a[y].blood){
		if(a[y].qiup())++a[y].blood;
		else godie(x,y);
	}
}
inline void godie(int x,int y){//x杀死了y
	a[y].dead=true;
	if(a[y].id==1){
		gameover=true;
		return;
	}
	if(a[y].id==3){
		--sumf;
		if(!sumf){
			gameover=true;
			return;
		}
		a[x].award();
	}
	if(a[y].id==2&&a[x].id==1)
		a[x].punish();
	a[a[y].prepig].nxtpig=a[y].nxtpig;
	a[a[y].nxtpig].prepig=a[y].prepig;
	allcal();
}
inline void kill(int x,int y){//x对y使用了一张杀
	if(a[x].id!=1&&a[x].appear<2){
		if(a[y].id==3)a[x].appear=2;
		else a[x].appear=3;
		allcal();
	}
	if(a[y].qiud())return;
	hurt(x,y);
}
inline void fight(int x,int y){//x对y决斗
	if(a[x].id!=1&&a[x].appear<2){
		if(a[y].id==3)a[x].appear=2;
		else a[x].appear=3;
		allcal();
	}
	if(a[y].id==1||a[y].appear==2)
		if(wuxiekeji(x,0))
			return;
	if(a[y].appear==3)
		if(wuxiekeji(x,1))
			return;
	if(a[x].id==1&&a[y].id==2){
		hurt(x,y);
		return;
	}
	while(1){
		if(!a[y].qiuk()){
			hurt(x,y);
			return;
		}
		if(!a[x].qiuk()){
			hurt(y,x);
			return;
		}
	}
}
inline void nanman(int x){//x使用了南蛮
	int y(a[x].nxtpig);
//  cout<<"now "<<x<<" is nanmaning"<<endl;
	while(y!=x){
		if(a[y].id==1||a[y].appear==2)
			if(wuxiekeji(x,0)){
//              cout<<"wuxiekeji "<<y<<endl;
				y=a[y].nxtpig;
				continue;
			}
		if(a[y].appear==3)
			if(wuxiekeji(x,1)){
//              cout<<"wuxiekeji "<<y<<endl;
				y=a[y].nxtpig;
				continue;
			}
		if(!a[y].qiuk()){
			hurt(x,y);
			if(gameover)return;
			if(y==1&&a[x].appear==0){
				a[x].appear=1;
				allcal();
			}
		}
		y=a[y].nxtpig;
	}
}
inline void wanjian(int x){//x使用了万箭
	int y(a[x].nxtpig);
	while(y!=x){
		if(a[y].id==1||a[y].appear==2)
			if(wuxiekeji(x,0)){
				y=a[y].nxtpig;
				continue;
			}
		if(a[y].appear==3)
			if(wuxiekeji(x,1)){
				y=a[y].nxtpig;
				continue;
			}
		if(!a[y].qiud()){
			hurt(x,y);
			if(gameover)return;
			if(y==1&&a[x].appear==0){
				a[x].appear=1;
				allcal();
			}
		}
		y=a[y].nxtpig;
	}
}
inline bool wuxiekeji(int pos,bool fan){
	bool st(fan);
	int last(pos),x(pos);
	if(fan==(a[x].id==3)){
		if(a[x].qiuj()){
			last=x;
			fan=!fan;
			if(a[x].appear<=2){
				a[x].appear=3-fan;
				allcal();
			}
		}
	}
	x=a[x].nxtpig;
	while(x!=last){
		if(fan==(a[x].id==3)){
			if(a[x].qiuj()){
				last=x;
				fan=!fan;
				if(a[x].appear<=2){
					a[x].appear=3-fan;
					allcal();
				}
			}
		}
		x=a[x].nxtpig;
	}
	return st!=fan;
}
int main(){
	freopen("kopk.in","r",stdin);
	freopen("kopk.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i)
		a[i].prepig=i-1,a[i].nxtpig=i+1;
	a[1].prepig=n,a[n].nxtpig=1;
	for(int i=1;i<=n;++i){
		scanf("%s",op);
		if(op[0]=='M')a[i].id=1,zhugong=i;
		if(op[0]=='Z')a[i].id=2;
		if(op[0]=='F')a[i].id=3,++sumf;
		for(int j=1;j<=4;++j){
			scanf("%s",op);
			paidui[++bot]=op[0];
		}
	}
	for(int i=1;i<=m;++i){
		scanf("%s",op);
		paidui[++bot]=op[0];
	}
	m+=(n<<2);
	for(int i=1;i<=n;++i){
		a[i].mopaistage();
		a[i].mopaistage();
		a[i].num=i;
	}
	allcal();
	int now(1);
	while(!gameover){
//      cout<<"now start "<<now<<" turn"<<endl;
		a[now].round();
		now=a[now].nxtpig;
//      cout<<"check the blood"<<endl;
//      for(int i=1;i<=n;++i)
//          cout<<i<<" is "<<((a[i].dead)?"dead\0":"live\0")<<" blood "<<a[i].blood<<endl;
	}
	if(a[zhugong].dead)puts("FP");
	else puts("MP");
	for(int i=1;i<=n;++i)
		a[i].print();
}