[SDOI2010] 猪国杀
写+调了一天,难受。写了刚好600行啊。幸好loj有数据
有一些细节:
锦囊牌生效前,先进行无懈可击的判定,要从发起该锦囊牌的猪开始。
每用一张牌都有可能使得前面的一张牌可用,所以要再从头开始判。
多看几遍题目描述再做,要用猪脑子去看。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cctype>
#include<string>
#include<iostream>
//#define DEBUG
#define qmin(x,y) (x=min(x,y))
#define qmax(x,y) (x=max(x,y))
using namespace std;
inline char gc() {
// static char buf[100000],*p1,*p2;
// return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
return getchar();
}
template<class T>
int read(T &ans) {
ans=0;char ch=gc();T f=1;
while(!isdigit(ch)) {
if(ch==EOF) return -1;
if(ch=='-') f=-1;
ch=gc();
}
while(isdigit(ch))
ans=ans*10+ch-'0',ch=gc();
ans*=f;return 1;
}
template<class T1,class T2>
int read(T1 &a,T2 &b) {
return read(a)!=EOF&&read(b)!=EOF?2:EOF;
}
template<class T1,class T2,class T3>
int read(T1 &a,T2 &b,T3 &c) {
return read(a,b)!=EOF&&read(c)!=EOF?3:EOF;
}
typedef long long ll;
typedef vector<int>::iterator vit;
const int inf=0x3f3f3f3f;
string s,las;
class pig {
#ifdef DEBUG
public :
#endif
int opt,dead,HP,zgln,tf,tz,fakef;
vector<int> pi;
public :
void getname() {
cin>>s;HP=4;
if(s=="MP") opt=2;
else if(s=="ZP") opt=1;
else opt=0;
}
bool hasdead() {return dead;}
bool MP() {return opt==2;}
bool FP() {return opt==0;}
bool ZP() {return opt==1;}
void addpi() {
if(cin>>s) las=s;
else s=las;
pi.push_back(s[0]);
}
void show() {
#ifdef DEBUG
printf("%d %d %d %d %d ",HP,fakef,tz,tf,zgln);
#endif
for(int i=0;i<pi.size();i++) {
if(i!=0) putchar(' ');
printf("%c",pi[i]);
}
putchar('\n');
}
bool fakeFP() {return fakef;}
bool hastf() {return tf;}
bool hastz() {return tz;}
bool noHP() {return HP<=0;}
bool havezb() {return zgln;}
bool fullHP() {return HP==4;}
void mpround(int);
void zpround(int);
void fpround(int);
bool finda(int x) {
for(vit i=pi.begin();i!=pi.end();i++)
if(*i==x) {
pi.erase(i);
return 1;
}
return 0;
}
void decrease() {
HP--;
if(noHP())
if(finda('P')) HP++;
else dead=1;
}
void clear() {
pi.clear();
zgln=0;
}
void addfakef() {
fakef=1;
}
void tiaof() {tf=1;}
void tiaoz() {tz=1;}
};
pig Pig[11];
int n,m,noshow=1;
int add(int x) {
if(x==n) return 1;
else return x+1;
}
bool end() {
for(int i=1;i<=n;i++)
if(Pig[i].hasdead()&&Pig[i].MP()) {
if(noshow) puts("FP"),noshow=0;
return 1;
}
else if(!Pig[i].hasdead()&&Pig[i].FP())
return 0;
if(noshow) puts("MP"),noshow=0;
return 1;
}
int mpusek(int bh) {
for(int i=add(bh);i!=bh;i=add(i))
if(!Pig[i].hasdead()) {
if((Pig[i].fakeFP()&&!Pig[i].hastz())||Pig[i].hastf()) {
if(!Pig[i].finda('D')) Pig[i].decrease();
return i;
}
break;
}
return 0;
}
bool fpneedj(int bh) ;
bool zpneedj(int bh) ;
bool fpneedj(int bh) {
int flag=1;
for(int i=bh;flag||i!=bh;i=add(i),flag=0)
if(!Pig[i].hasdead()&&Pig[i].FP()) {
if(Pig[i].finda('J')) {
Pig[i].tiaof();
if(!zpneedj(i))
return 1;
}
}
return 0;
}
bool zpneedj(int bh) {
int flag=1;
for(int i=bh;flag||i!=bh;i=add(i),flag=0)
if(!Pig[i].hasdead()&&(Pig[i].MP()||Pig[i].ZP())) {
if(Pig[i].finda('J')) {
Pig[i].tiaoz();
if(!fpneedj(i))
return 1;
}
}
return 0;
}
int mpusef(int bh) {
for(int i=add(bh);i!=bh;i=add(i))
if(!Pig[i].hasdead()) {
if((Pig[i].fakeFP()&&!Pig[i].hastz())||Pig[i].hastf()) {
if(Pig[i].ZP()) {
Pig[i].decrease();
if(Pig[i].hasdead()) return 1;
return 0;
}
else {
if(Pig[i].hastf())
if(fpneedj(bh)) return 0;
for(int j=1;;j++) {
if(j&1) {
if(!Pig[i].finda('K')) {
Pig[i].decrease();
}
if(Pig[i].hasdead()) return 2;
return 0;
}
else {
if(!Pig[bh].finda('K'))
Pig[bh].decrease();
return 0;
}
}
}
}
}
return -1;
}
void usen(int bh) {
for(int i=add(bh);i!=bh;i=add(i)) if(!Pig[i].hasdead()) {
if(Pig[i].FP()) {
if(!Pig[i].hastf()||!fpneedj(bh)) {
if(!Pig[i].finda('K')) {
Pig[i].decrease();
if(end()) return;
if(Pig[i].hasdead())
for(int j=1;j<=3;j++) Pig[bh].addpi();
}
}
}
else {
if(Pig[i].ZP()) {
if(!Pig[i].hastz()||!zpneedj(bh)) {
if(!Pig[i].finda('K')) {
Pig[i].decrease();
if(Pig[i].hasdead()&&Pig[bh].MP())
Pig[bh].clear();
}
}
}
else {
if(!zpneedj(bh)) {
if(!Pig[i].finda('K')) {
Pig[i].decrease();
Pig[bh].addfakef();
if(end()) return;
}
}
}
}
}
}
void usew(int bh) {
for(int i=add(bh);i!=bh;i=add(i)) if(!Pig[i].hasdead()) {
if(Pig[i].FP()) {
if(!Pig[i].hastf()||!fpneedj(bh)) {
if(!Pig[i].finda('D')) {
Pig[i].decrease();
if(end()) return;
if(Pig[i].hasdead())
for(int j=1;j<=3;j++) Pig[bh].addpi();
}
}
}
else {
if(Pig[i].ZP()) {
if(!Pig[i].hastz()||!zpneedj(bh)) {
if(!Pig[i].finda('D')) {
Pig[i].decrease();
if(Pig[i].hasdead()&&Pig[bh].MP())
Pig[bh].clear();
}
}
}
else {
if(!zpneedj(bh)) {
if(!Pig[i].finda('D')) {
Pig[i].decrease();
Pig[bh].addfakef();
if(end()) return;
}
}
}
}
}
}
void pig::mpround(int bh) {
int flag=0;
for(vit i=pi.begin();i!=pi.end()&&!pi.empty();i++) {
mpnxt:;
{
#ifdef DEBUG
puts("@@@@@@@@@@@@");
for(int i=1;i<=n;i++)
if(Pig[i].hasdead()) puts("DEAD");
else Pig[i].show();
puts("@@@@@@@@@@@@");
#endif
}
if(pi.empty()||hasdead()||end()) break;
switch(*i) {
case 'P' :
if(!fullHP()) {
HP++,pi.erase(i),
i=pi.begin();goto mpnxt;
}
break;
case 'K' : {
if(!Pig[bh].havezb()&&flag) break;
int x=mpusek(bh);
if(x==0) break;
pi.erase(i);
if(end()) return;
if(Pig[x].FP()&&Pig[x].hasdead())
for(int i=1;i<=3;i++) addpi();
if(!Pig[x].FP()&&Pig[x].hasdead())
clear();
i=pi.begin();
flag=1;goto mpnxt;
break;
}
case 'Z' : {
pi.erase(i);
i=pi.begin();
zgln=1;
i=pi.begin();goto mpnxt;
break;
}
case 'F' : {
int x=mpusef(bh);
if(x==-1) break;
pi.erase(i);
i=pi.begin();
if(end()) return;
if(x==1)
clear();
if(x==2)
for(int j=1;j<=3;j++) addpi();
goto mpnxt;
break;
}
case 'N' : {
pi.erase(i);
usen(bh);
i=pi.begin();
if(end()) return;
goto mpnxt;
break;
}
case 'W' : {
pi.erase(i);
usew(bh);
i=pi.begin();
if(end()) return;
goto mpnxt;
break;
}
}
}
}
int fpusek(int bh) {
for(int i=add(bh);i!=bh;i=add(i))
if(!Pig[i].hasdead()) {
if(Pig[i].hastz()||Pig[i].MP()) {
Pig[bh].tiaof();
if(!Pig[i].finda('D'))
Pig[i].decrease();
return 1;
}
break;
}
return 0;
}
void fpusef(int bh) {
int mp;Pig[bh].tiaof();
for(int i=1;i<=n;i++)
if(Pig[i].MP()) mp=i;
if(zpneedj(bh)) return;
for(int i=1;;i++)
if(i&1)
if(!Pig[mp].finda('K')) {
Pig[mp].decrease();
break;
}
else ;
else
if(!Pig[bh].finda('K')) {
Pig[bh].decrease();
break;
}
else ;
if(end()) return;
if(Pig[bh].hasdead())
for(int i=1;i<=3;i++)
Pig[mp].addpi();
}
void pig::fpround(int bh) {
int flag=0;
for(vit i=pi.begin();i!=pi.end()&&!hasdead()&&!pi.empty();i++) {
fpnxt:;
{
#ifdef DEBUG
puts("@@@@@@@@@@@@");
for(int i=1;i<=n;i++)
if(Pig[i].hasdead()) puts("DEAD");
else Pig[i].show();
puts("@@@@@@@@@@@@");
#endif
}
if(pi.empty()||hasdead()||end()) break;
switch(*i) {
case 'K' : {
if(flag&&!zgln) continue;
int x=fpusek(bh);
if(!x) break;
flag=1;
pi.erase(i);
i=pi.begin();
if(end()) return;
goto fpnxt;
break;
}
case 'P' : {
if(!fullHP()) {
HP++,pi.erase(i);
i=pi.begin();
goto fpnxt;
}
break;
}
case 'F' : {
fpusef(bh);
pi.erase(i);
i=pi.begin();
if(end()) return;
goto fpnxt;
break;
}
case 'N' : {
pi.erase(i);
usen(bh);
i=pi.begin();
if(end()) return;
goto fpnxt;
break;
}
case 'W' : {
pi.erase(i);
usew(bh);
i=pi.begin();
if(end()) return;
goto fpnxt;
break;
}
case 'Z' : {
zgln=1;
pi.erase(i);
i=pi.begin();
goto fpnxt;
break;
}
}
}
}
int zpusek(int bh) {
for(int i=add(bh);i!=bh;i++)
if(!Pig[i].hasdead()) {
if(Pig[i].hastf()) {
Pig[bh].tiaoz();
if(!Pig[i].finda('D')) Pig[i].decrease();
return i;
}
break;
}
return 0;
}
int zpusef(int bh) {
for(int i=add(bh);i!=bh;i=add(i))
if(!Pig[i].hasdead()&&Pig[i].hastf()) {
Pig[bh].tiaoz();
if(fpneedj(bh)) return i;
for(int j=1;;j++)
if(j&1) {
if(!Pig[i].finda('K')) {
Pig[i].decrease();
return i;
}
}
else {
if(!Pig[bh].finda('K')) {
Pig[bh].decrease();
return bh;
}
}
}
return 0;
}
void pig::zpround(int bh) {
int flag=0;
for(vit i=pi.begin();i!=pi.end()&&!hasdead()&&!pi.empty();i++) {
zpnxt:;
{
#ifdef DEBUG
puts("@@@@@@@@@@@@");
for(int i=1;i<=n;i++)
if(Pig[i].hasdead()) puts("DEAD");
else Pig[i].show();
puts("@@@@@@@@@@@@");
#endif
}
if(pi.empty()||hasdead()||end()) break;
switch(*i) {
case 'K' : {
if(flag&&!zgln) continue;
int x=zpusek(bh);
if(x==0) continue;
flag=1;
pi.erase(i);
i=pi.begin();
if(end()) return;
if(Pig[x].hasdead())
for(int j=1;j<=3;j++) addpi();
goto zpnxt;
break;
}
case 'F' : {
int x=zpusef(bh);
if(x==0) continue;
pi.erase(i);
i=pi.begin();
if(end()) return;
if(Pig[x].hasdead()&&x!=bh)
for(int j=1;j<=3;j++) addpi();
goto zpnxt;
break;
}
case 'N' : {
pi.erase(i);
usen(bh);
i=pi.begin();
if(end()) return;
goto zpnxt;
break;
}
case 'W' : {
pi.erase(i);
usew(bh);
i=pi.begin();
if(end()) return;
goto zpnxt;
break;
}
case 'Z' : {
pi.erase(i);
zgln=1;
i=pi.begin();
goto zpnxt;
break;
}
case 'P' : {
if(!fullHP()) {
pi.erase(i);
i=pi.begin();
HP++;
goto zpnxt;
}
break;
}
}
}
}
signed main() {
// freopen("test.in","r",stdin);
// freopen("out","w",stdout);
read(n,m);
for(int i=1;i<=n;i++) {
Pig[i].getname();
for(int j=1;j<=4;j++)
Pig[i].addpi();
}
int now=1;
for(;!end();now=add(now)) if(!Pig[now].hasdead()) {
Pig[now].addpi(),Pig[now].addpi();
if(Pig[now].MP())
Pig[now].mpround(now);
else if(Pig[now].FP())
Pig[now].fpround(now);
else Pig[now].zpround(now);
#ifdef DEBUG
puts("************");
for(int i=1;i<=n;i++)
if(Pig[i].hasdead()) puts("DEAD");
else Pig[i].show();
puts("************");
#endif
}
for(int i=1;i<=n;i++)
if(Pig[i].hasdead()) puts("DEAD");
else Pig[i].show();
return 0;
}