记录编号 |
458718 |
评测结果 |
AAAAAAAAAAAAAAAAAAAA |
题目名称 |
[SDOI 2010] 猪国杀 |
最终得分 |
100 |
用户昵称 |
Hzoi_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;
}