搞了两天只有20pts
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <stdlib.h>
#include <algorithm>
#include <map>
#include <queue>
#include <vector>
//#pragma GCC optimize(2) //吸氧
//#pragma GCC optimize(3,"Ofast","inline") //吸臭氧
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
inline int read(){
char ch=getchar();
int x=0,w=1;
while(ch<'0'||ch>'9'){
if(ch=='-')
w=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=(x<<3)+(x<<1)+(ch^48);
ch=getchar();
}
return x*w;
}
struct pig{
int card_size,hp,front,next;
char id,card[2005];//id->身份
bool zgln;//是否装备猪哥连弩
}p[15];
char king_thought[15],card_heap[2005],ch[10];
//king_thought->在主公眼里这只猪的身份
//card_heap->卡牌堆
int n,m,rebel_num;//rebel_num->反贼数量
bool ed;//游戏是否结束
/*
桃->P
杀->K
闪->D
决斗->F
南猪入侵->N
万箭齐发->W
无懈可击->J
猪哥连弩->Z
空牌->E(Empty)
主猪->M
忠猪->Z
反猪->F
类反猪->L
不知道猪->E
*/
void get_card(int pig){//摸牌
if(!m) m++;//牌库为空之后再抽牌,会重复抽最后一张被抽走牌
p[pig].card[++p[pig].card_size]=card_heap[m];
m--;
}
void judge_die(int from,int to){//pig_from击杀了pig_to
//判断是否有桃
for(int i=1;i<=p[to].card_size;i++){
if(p[to].card[i]=='P'){
p[to].card[i]='E';
p[to].hp++;
return;
}
}
//死亡后改变猪之间的距离
/*
1--2--3
3.front=2,1.next=2;
1-kill-->2;
3.front=1,1.next=3;
*/
p[p[to].next].front=p[to].front;
p[p[to].front].next=p[to].next;
//判断游戏是否结束
if(p[to].id=='M' || to==1){//主猪死亡 游戏结束
ed=true;
return;
}
if(p[to].id=='F')//反猪死亡
rebel_num--;
if(!rebel_num){//反猪全部死亡 游戏结束
ed=true;
return;
}
if(p[to].id=='F'){//击杀反猪 摸三张牌
get_card(from);
get_card(from);
get_card(from);
}
if((p[from].id=='M' || from==1) && p[to].id=='Z'){//主猪击杀忠猪 弃牌
p[from].card_size=0;
p[from].zgln=false;
}
}
void kill(int from,int to){//杀
//判断是否有闪
for(int i=1;i<=p[to].card_size;i++){
if(p[to].card[i]=='D'){
p[to].card[i]='E';
return;
}
}
p[to].hp--;
//空血进入判定是否死亡
if(p[to].hp<=0)
judge_die(from,to);
}
bool invulnerable(int p1,int p2,int p3){//无懈可击
int num=p1;
while(1){
if(p[p3].id=='M' || p3==1){
if(king_thought[p2]==p[num].id || (king_thought[p2]=='M' && p[num].id=='Z') || (king_thought[p2]=='Z' && p[num].id=='M')){
for(int i=1;i<=p[num].card_size;i++){
if(p[num].card[i]=='J'){
p[num].card[i]='E';
king_thought[num]=p[num].id;
return !invulnerable(num,p1,0);
}
}
}
}
else{
if(((p[num].id=='M' || p[num].id=='Z') && king_thought[p1]=='F') || (p[num].id=='F' && (king_thought[p1]=='M' || king_thought[p1]=='Z'))){
for(int i=1;i<=p[num].card_size;i++){
if(p[num].card[i]=='J'){
p[num].card[i]='E';
return !invulnerable(num,p1,0);
}
}
}
}
num=p[num].next;
if(num==p1)
break;
}
return false;
}
void pig_breakout(int from){//南猪入侵
for(int to=p[from].next;to!=from;to=p[to].next){
if(!invulnerable(from,to,1)){
int i;
for(i=1;i<=p[to].card_size;i++){
if(p[to].card[i]=='K'){
p[to].card[i]='E';
return;
}
}
if(i>p[to].card_size){
p[to].hp--;
//主猪会认为没有跳身份,且用南猪入侵对自己造成伤害的猪是类反猪
if((p[to].id=='M' || to==1) && king_thought[from]=='E')
king_thought[from]='L';
if(p[to].hp<=0)
judge_die(from,to);
if(ed)
return;
}
}
}
}
void ten_thouand_arrows(int from){//万箭齐发
for(int to=p[from].next;to!=from;to=p[to].next){
if(!invulnerable(from,to,1)){
int i;
for(i=1;i<=p[to].card_size;i++){
if(p[to].card[i]=='D'){
p[to].card[i]='E';
return;
}
}
if(i>p[to].card_size){
p[to].hp--;
//主猪会认为没有跳身份,且用万箭齐发对自己造成伤害的猪是类反猪
if((p[to].id=='M' || to==1) && king_thought[from]=='E')
king_thought[from]='L';
if(p[to].hp<=0)
judge_die(from,to);
if(ed)
return;
}
}
}
}
void dule(int from,int to){//决斗
if(invulnerable(from,to,1))
return;
if((p[from].id=='M' || from==1) && p[to].id=='Z'){//忠猪决斗时,如果对方是主猪,那么不会弃置杀
p[to].hp--;
if(p[to].hp<=0)
judge_die(from,to);
return;
}
int i=1,j=1;
while(1){
while(p[to].card[i]!='K' && i<=p[to].card_size)
i++;
if(i>p[to].card_size){
p[to].hp--;
if(p[to].hp<=0)
judge_die(from,to);
return;
}
else
p[to].card[i]='E';
while(p[from].card[j]!='K' && j<=p[from].card_size)
j++;
if(j>p[from].card_size){
p[from].hp--;
if(p[from].hp<=0)
judge_die(to,from);
return;
}
else
p[from].card[j]='E';
}
}
void do_round(){
char now_card;
ed=true;
if(rebel_num)
ed=false;
if(ed)
return;
for(int i=1;i;i=p[i].next){
if(p[i].hp<=0)
continue;
get_card(i);
get_card(i);
bool if_kill=true;//判断是否还能继续用杀
for(int j=1;j<=p[i].card_size;j++){
now_card=p[i].card[j];
if(now_card=='E')//空牌跳过
continue;
if(now_card=='P'){//桃
if(p[i].hp!=4){
p[i].card[j]='E';
p[i].hp++;
continue;
}
}
if(now_card=='K'){//杀
if(if_kill==false && p[i].zgln==false)
continue;
if(p[i].id=='M' && king_thought[p[i].next]!='L' && king_thought[p[i].next]!='F')
continue;
if(p[i].id=='Z' && king_thought[p[i].next]!='F')
continue;
if(p[i].id=='F' && king_thought[p[i].next]!='Z' && king_thought[p[i].next]!='M')
continue;
p[i].card[j]='E';
kill(i,p[i].next);
king_thought[i]=p[i].id;
if_kill=false;
if(ed)
return;
continue;
}
if(now_card=='F'){//决斗
if(p[i].id=='F'){
p[i].card[j]='E';
dule(i,1);//反猪对于每种表敌意的方式,如果有机会则对主猪表
king_thought[i]=p[i].id;
if(ed)
return;
j=0;
continue;
}
for(int to=p[i].next;to!=i;to=p[to].next){
if((p[i].id=='M' && (king_thought[to]=='F' || king_thought[to]=='L')) || (p[i].id=='Z' && king_thought[to]=='F')){
p[i].card[j]='E';
dule(i,to);
king_thought[i]=p[i].id;
if(ed)
return;
j=0;
continue;
}
}
}
if(now_card=='N'){//南猪入侵
p[i].card[j]='E';
pig_breakout(i);
if(ed)
return;
j=0;
continue;
}
if(now_card=='W'){//万箭齐发
p[i].card[j]='E';
ten_thouand_arrows(i);
if(ed)
return;
j=0;
continue;
}
if(now_card=='Z'){//猪哥连弩
p[i].card[j]='E';
p[i].zgln=true;
j=0;
continue;
}
}
}
}
int main(int argc, const char * argv[]) {
n=read();m=read();
for(int i=1;i<=n;i++){
p[i].front=i-1;
p[i].next=i+1;
}
p[1].front=n;
p[n].next=1;
for(int i=1;i<=n;i++){
for(int j=1;j<2005;j++)
p[i].card[j]='E';
p[i].hp=4;
p[i].card_size=4;
scanf("%s",ch);
p[i].id=ch[0];
for(int j=1;j<=4;j++){
scanf("%s",ch);
p[i].card[j]=ch[0];
}
if(p[i].id=='F')
rebel_num++;
p[i].zgln=false;
}
for(int i=1;i<=n;i++)
king_thought[i]='E';
king_thought[1]='M';
for(int i=m;i>=1;i--){
scanf("%s",ch);
card_heap[i]=ch[0];
}
do_round();
if(p[1].hp<=0)
printf("FP\n");
else
printf("MP\n");
for(int i=1;i<=n;i++){
if(p[i].hp<=0)
printf("DEAD\n");
else{
for(int j=1;j<=p[i].card_size;j++)
if(p[i].card[j]!='E')
printf("%c ",p[i].card[j]);
printf("\n");
}
}
return 0;
}