记录编号 458718 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [SDOI 2010] 猪国杀 最终得分 100
用户昵称 GravatarHzoi_Ivan 是否通过 通过
代码语言 C++ 运行时间 0.021 s
提交时间 2017-10-11 19:29:43 内存使用 1.11 MiB
显示代码纯文本
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
int n,m;
char pai[2505][5];
char pp[25]={'K','D','P','F','N','W','J','Z'};
int pai_top;
void die(int,int);
struct pig{
	int blood;int id;  //0主 1忠 2反 3跳忠 4跳反
	int lfp;//类反猪 
	int zb;//装备 
	int hp[2050];//0杀 1闪 2桃 3决斗 4南蛮 5万箭 6无懈 7弩
	int first,last;//最后一张手牌编号 
	int pre[2050],nxt[2050],tmp[2050],num;
	pig(){
		blood=4;id=num=zb=lfp=last=first=0;
		memset(hp,0,sizeof hp);
		memset(pre,0,sizeof pre);
		memset(nxt,0,sizeof nxt);
		memset(tmp,0,sizeof tmp);
	}
	void in_id(){
		char ch[5]; scanf("%s",ch);
		if(ch[0]=='M')id=0;
		else if(ch[0]=='Z')id=1;
		else id=2;
	}
	void del(int x){
		nxt[pre[x]]=nxt[x];pre[nxt[x]]=pre[x];
		if(x==last)last=pre[x];
		if(x==first)first=nxt[x];
	}
	bool find(int x){
		for(int i=first;i;i=nxt[i])
			if(hp[i]==x){del(i);return 1;}
		return 0;
	}
	void hurt(int x,int y){
		blood--;
		if(blood==0){
			if(!find(2))::die(x,y);
			else blood++;
		}
	}
	void change(int x){
		if(x==1){
			if(id==1)id=3;
			if(id==2)id=4;
			lfp=0;
		}
		else lfp=1;
	}
	void take(char *ch){
		if(!ch[0])ch[0]=pai[m][0];
		if(ch[0]=='K')hp[++num]=0;
		if(ch[0]=='D')hp[++num]=1;
		if(ch[0]=='P')hp[++num]=2;
		if(ch[0]=='F')hp[++num]=3;
		if(ch[0]=='N')hp[++num]=4;
		if(ch[0]=='W')hp[++num]=5;
		if(ch[0]=='J')hp[++num]=6;
		if(ch[0]=='Z')hp[++num]=7;
		if(last==0)first=num;
		pre[num]=last;nxt[last]=num;
		nxt[num]=0;pre[0]=num;last=num;
	}
}p[25];
int pre[25],nxt[25],used_kill;
void print(){
	for(int i=1;i<=n;i++){
		if(p[i].blood==0){printf("DEAD\n");}
		else{
			bool bo=0;
			for(int j=p[i].first;j;j=p[i].nxt[j]){
				if(bo){printf(" ");}
				bo=1;
				if(p[i].hp[j]==0){printf("K");}
				if(p[i].hp[j]==1){printf("D");}
				if(p[i].hp[j]==2){printf("P");}
				if(p[i].hp[j]==3){printf("F");}
				if(p[i].hp[j]==4){printf("N");}
				if(p[i].hp[j]==5){printf("W");}
				if(p[i].hp[j]==6){printf("J");}
				if(p[i].hp[j]==7){printf("Z");}
			}
			printf("\n");
		}
	}
}
bool check(){
	bool b0=0,b2=0;
	for(int i=1;i<=n;i++){
		if(p[i].blood>0){
			if(p[i].id==0)b0=1;
			if(p[i].id==2||p[i].id==4)b2=1;
		}
	}
	if(b0==1&&b2==1)return 0;
	else if(b0==0)printf("FP\n");
	else printf("MP\n");
	return 1; 
}
void die(int x,int y){
	nxt[pre[y]]=nxt[y];
	pre[nxt[y]]=pre[y];
	if(check()){print();exit(0);}
	if(p[y].id==2||p[y].id==4)
	{p[x].take(pai[++pai_top]);p[x].take(pai[++pai_top]);p[x].take(pai[++pai_top]);}
	if(p[x].id==0&&(p[y].id==1||p[y].id==3)){
		memset(p[x].hp,0,sizeof p[x].hp);
		memset(p[x].pre,0,sizeof p[x].pre);
		memset(p[x].nxt,0,sizeof p[x].nxt);
		memset(p[x].tmp,0,sizeof p[x].tmp);
		p[x].zb=0; p[x].first=p[x].last=0;
	}
}
bool hate_check(int x,int y){
	if(p[x].id==0&&(p[y].id==4||p[y].lfp==1))return 1;
	if((p[x].id==1||p[x].id==3)&&p[y].id==4)return 1;
	if((p[x].id==2||p[x].id==4)&&(p[y].id==0||p[y].id==3))return 1;
	return 0;
}
bool love_check(int x,int y){
	if(p[x].id==0&&(p[y].id==3||p[y].id==0))return 1;
	if((p[x].id==1||p[x].id==3)&&(p[y].id==3||p[y].id==0))return 1;
	if((p[x].id==2||p[x].id==4)&&p[y].id==4)return 1;
	return 0;
}
bool make_hate(int be,int x){
	for(int i=be,bo=0;(bo!=1||i!=be);i=nxt[i]){
		bo=1;
		if(hate_check(i,x))
			if(p[i].find(6)){
				p[i].change(1);
				if(!make_hate(i,i))return 1;
			}
	}
	return 0;
}
bool make_love(int be,int x){
	for(int i=be,bo=0;(bo!=1||i!=be);i=nxt[i]){
		bo=1;
		if(love_check(i,x))
			if(p[i].find(6)){
				p[i].change(1);
				if(!make_hate(i,i))return 1;
			}
	}
	return 0;
}
void kill(int x,int y)
{if(!p[y].find(1)){p[y].hurt(x,y);}}
void fight(int x,int y){
	if(p[x].id==0&&(p[y].id==1||p[y].id==3)){
		p[y].hurt(x,y);
		return ;
	}
	if(make_love(x,y))return ;
	int now=y,de=x^y;
	while(p[now].find(0))now^=de;
	p[now].hurt(now^de,now);
}
void aoe(int x,int y){
	for(int i=nxt[x];i!=x;i=nxt[i]){
		if(make_love(x,i))continue;
		if(!p[i].find(y)){
			p[i].hurt(x,i);
			if(p[i].id==0&&(p[x].id==1||p[x].id==2)){p[x].change(0);}
		}
	}
}
bool check(int now,int x){//0杀 1闪 2桃 3决斗 4南蛮 5万箭 6无懈 7弩 8装备区 
	if(p[now].hp[x]==0){
		if(hate_check(now,nxt[now])&&(used_kill==0||p[now].zb==1)){
			p[now].del(x);p[now].change(1);
			kill(now,nxt[now]); used_kill=1;
			return 1;
		}
		else return 0;
	}
	if(p[now].hp[x]==1){return 0;}
	if(p[now].hp[x]==2){
		if(p[now].blood<4){p[now].del(x);p[now].blood++;return 1;}
		else return 0;
	}
	if(p[now].hp[x]==3){
		if(hate_check(now,1)){
			p[now].del(x);p[now].change(1);
			fight(now,1);
			return 1;
		}
		for(int i=nxt[now];i!=now;i=nxt[i]){
			if(hate_check(now,i)){
				p[now].del(x);p[now].change(1);
				fight(now,i);
				return 1;
			}
		}
		return 0;
	}
	if(p[now].hp[x]==4){p[now].del(x);aoe(now,0);return 1;}
	if(p[now].hp[x]==5){p[now].del(x);aoe(now,1);return 1;}
	if(p[now].hp[x]==6){return 0;}
	if(p[now].hp[x]==7){p[now].del(x);p[now].zb=1;return 1;}
	return 0;
}
int work(int now){
	int x=p[now].nxt[0];
	while(x&&!check(now,x))x=p[now].nxt[x];
	return x;
}
int main(){
    freopen("kopk.in","r",stdin);
    freopen("kopk.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)pre[i]=i-1,nxt[i]=i+1;
	pre[1]=n;nxt[n]=1;
	for(int i=1;i<=n;i++){
		p[i].in_id();
		char ch[2];
		scanf("%s",ch);p[i].take(ch);
		scanf("%s",ch);p[i].take(ch);
		scanf("%s",ch);p[i].take(ch);
		scanf("%s",ch);p[i].take(ch);
	}
	for(int i=1;i<=m;i++)scanf("%s",pai[i]);
	int now=1;
	int tim=0;
	while(1){
		tim++;
		used_kill=0;
		p[now].take(pai[++pai_top]);p[now].take(pai[++pai_top]);
		while(p[now].blood>0&&work(now));
		now=nxt[now];
		if(pai_top>m)pai_top=m;
	}
	return 0;
}