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++); } } }