记录编号 | 458293 | 评测结果 | AAAAAAAAAAAAAAAAAAAA | ||
---|---|---|---|---|---|
题目名称 | [SDOI 2010] 猪国杀 | 最终得分 | 100 | ||
用户昵称 | 是否通过 | 通过 | |||
代码语言 | 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(); }