BZOJ1972: [Sdoi2010]猪国杀

“此题注意样例少了个J,且牌堆可能用完牌,若牌用完则不停取最后一张”。——hzwer

然后直接模拟,认真读题,理清思路。

#include<cstdio>
#include<list>
#include<cstdlib>
#define FOR(a,k)
	for(iter k=p[a].begin();k!=p[a].end();++k)
using namespace std;
const int N=10;
int n,m,hp[N],st[N];
bool id[N],z[N];
list<char>p[N];
typedef list<char>::iterator iter;
char q[2005];
void draw(int a,int v){
	static int s;
	while(v--)
		p[a].push_back(q[s+1^m?s++:s]);
}
int next(int a){
	for(++a%=n;!hp[a];++a%=n);
	return a;
}
bool check(){
	for(int i=0;i!=n;++i)
		if(id[i]&&hp[i])return 0;
	return 1;
}
void output(bool j){
	puts(j?"FP":"MP");
	for(int i=0;i!=n;++i)
		if(!hp[i])
			puts("DEAD");
		else{
			int s=0;
			FOR(i,k){
				q[s++]=*k;
				q[s++]=32;
			}
			q[s-!!s]=0;
			puts(q);
		}
	exit(0);
}
bool find(int a,char v){
	FOR(a,k)if(*k==v){
		p[a].erase(k++);
		return 1;
	}
	return 0;
}
void kill(int a,int b,iter&k){
	if(!--hp[b])
		if(find(b,'P'))
			++hp[b];
		else if(check()){
			p[a].erase(k++);
			output(0);
		}
		else if(!b){
			p[a].erase(k++);
			output(1);
		}
		else if(id[b])
			draw(a,3);
		else if(!a){
			p[a]=list<char>(1);
			z[a]=0;
			k=p[a].begin();
		}
}
void fight(int a,int b,iter&k){
	if(!a&&!id[b])
		return kill(a,b,k);
	iter s[]={
		p[a].begin(),p[b].begin()
	};
	int c[]={a,b},v=1;
	iter*i=s+v;
	while(*i!=p[c[v]].end())
		if(**i!='K')
			++*i;
		else{
			*i=p[c[v]].erase(*i);
			i=s+(v^=1);
		}
	kill(c[v^1],c[v],k);
}
bool query(int a,int b){
	if(st[b]<0||st[b]>1)
		return 0;
	int i=a;
	bool v=0,res=0;
	do
		if(id[i]==(st[b]^v)&&find(i,'J')){
			st[i]=id[i];
			a=b=i;
			v|=1;
			res^=1;
		}
	while((i=next(i))!=a);
	return res;
}
void attack(int a,int b,iter&k){
	if(*k=='K'&&!find(b,'D'))
		kill(a,b,k);
	if(*k=='F'&&!query(a,b))
		fight(a,b,k);
	if(!(st[b]<0||st[b]>1))
		st[a]=st[b]^1;
}
char scan(){
	static char s[3];
	scanf("%s",s);
	return*s;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=0;i!=n;++i){
		hp[i]=4,st[i]=-1;
		if(scan()=='F')
			id[i]=1;
		for(int j=0;j!=4;++j)
			p[i].push_back(scan());
	}
	st[0]=0;
	for(int i=0;i!=m;++i)
		q[i]=scan();
	if(check())
		output(0);
	for(int i=0;;i=next(i)){
		draw(i,2);
		bool y=0;
		while(hp[i]){
			iter k=p[i].begin();
			int a=next(i),b=a;
			if(id[i]){
				if(st[a])
					a=i;
				b=0;
			}
			else if(i){
				if(st[a]!=1)
					a=i;
				while(b!=i&&st[b]!=1)
					b=next(b);
			}
			else{
				if(st[a]<1)
					a=i;
				while(b!=i&&st[b]<1)
					b=next(b);
			}
			while(k!=p[i].end()&&(*k=='D'||*k=='J'||*k=='P'&&hp[i]==4||*k=='K'&&(a==i||y&&!z[i])||*k=='F'&&b==i))
				++k;
			if(k==p[i].end())
				break;
			if(*k=='P')++hp[i];
			if(*k=='K'&&(!y++||z[i]))
				attack(i,a,k);
			if(*k=='F')
				attack(i,b,k);
			if(*k=='N'||*k=='W'){
				int j=i;
				while((j=next(j))!=i)
					if(!query(i,j)&&!find(j,*k=='N'?'K':'D')){
						kill(i,j,k);
						!j&&!~st[i]?st[i]=2:0;
					}
			}
			if(*k=='Z')z[i]=1;
			p[i].erase(k++);
		}
	}
}
原文地址:https://www.cnblogs.com/f321dd/p/5495969.html