题解 P2482 【[SDOI2010]猪国杀】

· · 题解

概述

这个显然是一道大模拟 比较坑的地方是如果大牌堆没有了,就要人工制造不断返回最后一张牌

可能是我比较弱吧,我写了4天812行,在写到600多行的时候发现无法处理"无懈可击操作"还删掉了400多行2333

我的代码有很多cerr和stderr如果你想了解这些沙雕猪是如何玩的,就把注释都打开就可以了,可以冷静胡乱分析

这可能题解们中不多的几篇使用真·指针的代码,确实考验人,我就因为搞了个野指针,debug了半天233333

最后NOIP2018rp++

812行代码预警

代码

不要问我为什么这么沙雕的写了两个函数用来处理牌

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include<cstring>
#include<string>
#include<cctype>
#include<cstdlib>
#include<map>
#include<ctime>
#define debuglog(x) cerr<<"\tdebug:"<<#x<<endl
#define debug(x) cerr<<"\tdebug:"<<#x<<"="<<(x)<<endl
#define debugg(x,y) cerr<<"\tdebug;"<<(x)<<":"<<#y<<"="<<(y)<<endl
#define debugzu(x,a,b)  cerr<<"\tdebug:"<<#x<<"=\n\t";for(int i=a;i<b;i++)cerr<<x[i]<<" ";fprintf(stderr,"\n");
#define debugerzu(x,a,b,c,d)    cerr<<"\tdebug:"<<#x<<"=\n\t";for(int i=a;i<b;i++,fprintf(stderr,"\n\t"))for(int j=c;j<d;j++)cerr<<x[i][j]<<" ";fprintf(stderr,"\n");
#define START clock_t __start=clock();
#define STOP fprintf(stderr,"\n\nUse Time:%fs\n",((double)(clock()-__start)/CLOCKS_PER_SEC));
using namespace std;
#define MAXN 11
#define MAXM 2011
#define PAI_USED 0 //用过了
#define P 1 //桃
#define K 2 //杀
#define D 3 //闪
#define F 4 //决斗
#define N 5 //南猪入侵
#define W 6 //万箭齐发
#define J 7 //无懈可击
#define Z 8 //猪哥连弩
#define TYPE_UNKNOW 0//类型未知
#define MP  1   //主猪 
#define ZP  2   //忠猪
#define FP  3   //反猪
#define LZP 4   //类忠猪
#define LFP 5   //类反猪
inline long long read()
{
    register long long x;register bool f;register char c;
    for (f=0; (c=getchar())<'0'||c>'9'; f=c=='-');
    for (x=c-'0'; (c=getchar())>='0'&&c<='9'; x=(x<<3)+(x<<1)+c-'0');
    return f?-x:x;
}
inline char readc()
{
    register char c;
    for (;((c=getchar())<'A'||c>'Z')&&(c<'a'||c>'z'););
    return c;
}
inline int readpai()
{
    switch(readc())
    {
        case 'P':
            return P;
        case 'K' :
            return K;
        case 'D':
            return D;
        case 'F' :
            return F;
        case 'N':
            return N;
        case 'W' :
            return W;
        case 'J' :
            return J;
        case 'Z' :
            return Z;               
    }
}
inline char getpai(int pai)
{
    switch(pai)
    {
        case P:
            return 'P';
        case K :
            return 'K';
        case D:
            return 'D';
        case F :
            return 'F';
        case N:
            return 'N';
        case W :
            return 'W';
        case J :
            return 'J';
        case Z :
            return 'Z';
        case PAI_USED :
            return 'U';
        default :
            return '!';
    }   
}
inline int readtype()
{
    string s;
    cin>>s;
    if(s=="MP")
        return MP;
    else if(s=="ZP")
        return ZP;
    else if(s=="FP")
        return FP;
}
inline string gettype(int x)
{
    if(x==MP)
        return "MP";
    else if(x==ZP)
        return "ZP";
    else if(x==FP)
        return "FP";
}
class pai_class
{
    private:
        int pai[MAXM];
        int head;
        int tail;
    public:
        inline int add      (int type)          {pai[tail++]=type;return tail-1;}
        inline int get      ()                  {return pai[head];}
        inline int count    ()                  {return tail-head;}
        inline int del      ()                  {int tmp=pai[head];if(count()>1){head++;}return tmp;}
};
pai_class all_pai;
class link_list
{
    private:
        int val;
        link_list *pro;
        link_list *nxt;
    public :
        inline  int         get         ()              {return val;}
        inline  int         set         (int v)         {return val=v;}
        inline  link_list*  get_nxt     ()              {return nxt;}
        inline  link_list*  get_pro     ()              {return pro;}
        inline  link_list*  set_nxt     (link_list* p)  {return nxt=p;}
        inline  link_list*  set_pro     (link_list* p)  {return pro=p;}
        inline  void        del         ()              {val=0;if(pro!=NULL)pro->nxt=nxt;if(nxt!=NULL)nxt->pro=pro;nxt=NULL;pro=NULL;}
};
class zhu_pai_class
{
    private:
        link_list pai[MAXM];
        int p_count,d_count,j_count;
        bool z_flag;
        link_list *now,*head,*tail;
    public :
        inline void reset_now()
        {
            now=head;
        }
        inline void reset_now_to_tail()
        {
            now=tail;
        }       
        inline void reset_tail()
        {
            tail=head;
        }
        zhu_pai_class()
        {
            p_count=d_count=j_count=0;
            z_flag=false;
            head=pai;
            reset_now();
            reset_tail();
            now->set_nxt(NULL);
            now->set_pro(NULL);
        }
        inline void add(int type)
        {
            if(type==P)                 //桃子
                p_count++;
            if(type==J)                 //无懈可击
                j_count++;
            if(type==D)                 //闪
                d_count++;
            if(now==NULL)
                now=tail;
            now->set(type);
            now->set_nxt(now+1);
            now->get_nxt()->set_pro(now);
            now->get_nxt()->set_nxt(NULL);
            tail=now=now->get_nxt();
        }
        inline bool del(link_list * v)
        {
            if(v==NULL)
                return false;
            if(v->get()==P)
                p_count--;
            if(v->get()==J)
                j_count--;
            if(v->get()==D)
                d_count--;
            if(head==v)
            {
                head=v->get_nxt();
//              cerr<<"\treset head"<<endl;
            }
            if(now==v)
            {
                now=v->get_nxt();
//              cerr<<"\treset now"<<endl;              
            }
//          cerr<<"\t\t lose "<<getpai(v->get())<<endl;
            v->del();
            return true;
        }
        inline link_list *get_now()
        {
            return now;
        }
        inline link_list *get_nxt()
        {
            if(tail==head)
                return NULL;
            return now=now->get_nxt();
        }
        inline link_list * find_d()     //返回第一张闪
        {
            reset_now();
            link_list *tmp=get_now();
            if(tmp==NULL)
                return NULL;
            do
                if(tmp->get()==D)
                    break;
            while((tmp=get_nxt())!=NULL);
            return tmp;
        }
        inline link_list * find_p()     //返回第一张桃
        {
            reset_now();
            link_list *tmp=get_now();
            if(tmp==NULL)
                return NULL;
            do
                if(tmp->get()==P)
                    break;
            while((tmp=get_nxt())!=NULL);
            return tmp;
        }
        inline link_list * find_j()     //返回第一张无懈可击
        {
            reset_now();
            link_list *tmp=get_now();
            if(tmp==NULL)
                return NULL;
            do
                if(tmp->get()==J)
                    break;
            while((tmp=get_nxt())!=NULL);
            return tmp;
        }
        inline bool try_use_k()         //尝试打出一张杀
        {
            reset_now();
            link_list *tmp=get_now();
            if(tmp==NULL)
                return false;           
            do
                if(tmp->get()==K)
                {
                    del(tmp);
                    return true;
                }
            while((tmp=get_nxt())!=NULL);
            return false;
        }
        inline bool try_use_d()         //尝试打出一张闪
        {
            if(d_count)
                return del(find_d());
            return false;
        }
        inline bool try_use_p()         //尝试打出一张桃
        {
            if(p_count)
            {
//              cerr<<"eat tao"<<endl;
                return del(find_p());
            }
            return false;
        }
        inline bool try_use_j()         //尝试打出一张无懈可击
        {
            if(j_count)
                return del(find_j());
            return false;
        }
        inline void print_all(FILE *f)
        {
            link_list *buf=now,*tmp;
            reset_now();
            tmp=now;
            if(tmp==NULL)
                return ;
            bool flag=false;
            do
            {
                if(tmp->get())
                {
                    if(flag)
                        fprintf(f," ");
                    flag=true;
                    fprintf(f,"%c",getpai(tmp->get()));
                }
            }
            while((tmp=get_nxt())!=NULL);
            fprintf(f,"\n");
            now=buf;
        }
        inline bool have_z()
        {
            return z_flag;
        }
        inline void add_z()
        {
            z_flag=true;
        }
        inline void del_all()
        {
            p_count=d_count=j_count=0;
            z_flag=false;
            reset_now();
            for(link_list *tmp=get_now(),*tmp2=tmp;tmp2;tmp2=tmp->get_nxt(),tmp->del(),tmp=tmp2);
            head=pai;
            reset_now();
            reset_tail();
            now->set(0);
            now->set_nxt(NULL);
            now->set_pro(NULL);     
        }
};
int alive_fanzei_count=0;
int alive_zhongzhu_count=0;
int n,m;
int ans;
#define UNKNOW 0
#define MPWIN 1
#define FPWIN 2
bool check_MP_alive();
void recal_all();
int in_zhuzu[MAXN];//在主猪心中类型
class pig_class;
pig_class* get_mp();
bool start_wx_circle(pig_class * start,bool y_is_fan);
class pig_class
{
    private :
        int type;//猪的类型
        int csf;//当前类型0没跳 1类反 2跳忠 3跳反
        bool alive;//活着没
        pig_class *next;
        pig_class *pro;
        pig_class *shouyao;//首要攻击目标
        pig_class *last;//最后一个伤害来源
        int id;
        int tili;
    public :
        zhu_pai_class pai;//牌
                            pig_class   ()              {tili=4;alive=true;type=TYPE_UNKNOW;shouyao=NULL;}
        inline  pig_class*  set_next    (pig_class *n)  {return next=n;}
        inline  pig_class*  set_pro     (pig_class *p)  {return pro=p;}
        inline  pig_class*  get_next    ()              {return next;}
        inline  pig_class*  get_pro     ()              {return pro;}
        inline  int         add_tili    ()              {return ++tili;}
        inline  int         del_tili    ()              {return --tili;}
        inline  int         get_tili    ()              {return tili;}      
        inline  int         set_id      (int i)         {return id=i;}
        inline  int         get_id      ()              {return id;}
        inline  int         set_type    (int i)         {if(i==FP)alive_fanzei_count++;else alive_zhongzhu_count++;return type=i;}
        inline  int         get_type    ()              {return type;}
        inline  int         set_csf     (int i)         {return csf=i;}
        inline  int         get_csf     ()              {return csf;}
        inline  bool        ifalive     ()              {return alive;}
        void die(pig_class *from)                           //料理这只猪的后事
        {
//          cerr<<"\t"<<get_id()<<" die by "<<from->get_id()<<endl;
            if(type==FP)
                alive_fanzei_count--;
            else
                alive_zhongzhu_count--;
            get_pro()->set_next(get_next());
            get_next()->set_pro(get_pro());
            alive=false;
            if(get_type()!=MP)
                if(get_type()==ZP&&from->get_type()==MP)
                {
//                  cerr<<"\tMP lose all pai"<<endl;
                    from->pai.del_all();
                }
            if(alive_fanzei_count<=0)
            {
                ans=MPWIN;
                return;
            }
            else if(alive_zhongzhu_count<=0)
            {
                ans=FPWIN;
                return;
            }
            else if(!check_MP_alive())//主猪死了
            {
                ans=FPWIN;
                return;
            }           
            if(get_type()==FP&&(!ans))
            {
//              last->pai.print_all(stderr);
                last->pai.reset_now_to_tail();
                last->pai.add(all_pai.del());
                last->pai.add(all_pai.del());
                last->pai.add(all_pai.del());
//              cerr<<"\t"<<last->get_id()<<" get 3 pai have";last->pai.print_all(stderr);
            }
            recal_all();
        }
        void hurt(pig_class *from)          //来自from的猪使这只猪-1s
        {
            last=from;
            if(del_tili()==0)               //快死了
                if(pai.try_use_p())         //尝试+1s
                    add_tili();             //+1s
                else
                {
                    die(from);              //拜拜甜甜圈
                    return ;
                }
//          cerr<<"\t"<<from->get_id()<<" hurt "<<get_id()<<" tili:"<<get_tili()<<endl;
        }
        void recal()                        //依据这只猪的信息更新其他猪
        {
            pig_class* y=get_next();
            if(get_type()==MP)
            {
                while(y!=this)
                {
                    if(y->get_csf()==1||y->get_csf()==3)
                    {
                        shouyao=y;
                        return ;
                    }
                    y=y->get_next();
                }
                shouyao=NULL;
            }
            else if(get_type()==ZP)
            {
                while(y!=this)
                {
                    if(y->get_csf()==3)
                    {
                        shouyao=y;
                        return ;
                    }
                    y=y->get_next();
                }
                shouyao=NULL;
            }
            else
            {
                while(y!=this)
                {
                    if(y->get_csf()==2||y->get_type()==1)
                    {
                        shouyao=y;
                        return ;
                    }
                    y=y->get_next();
                }
                shouyao=NULL;
            }
        }
        void round()
        {
            pai.reset_now_to_tail();
            pai.add(all_pai.del());
            pai.add(all_pai.del());     
            pai.reset_now();bool flag=false;
            bool usedsha=false;
            link_list *tmp=pai.get_now();
//          cerr<<""<<get_id()<<" have ";pai.print_all(stderr);
            while((!ans)&&(tmp=(flag?(pai.get_nxt()):(pai.get_now()))))
            {
                if(tmp==NULL)
                    return;
                if(!tmp->get())
                    return;
//              pai.print_all(stderr);
                flag=true;
//              cerr<<"\t"<<get_id()<<"use "<<getpai(tmp->get())<<endl;
                if(tmp->get()==D||tmp->get()==J)
                    continue;
                if(get_tili()!=4&&tmp->get()==P)                                                                //吃桃子
                {
                    pai.del(tmp);
                    pai.reset_now();flag=false;
                    add_tili();
//                  cerr<<"\t"<<get_id()<<"have "<<get_tili()<<" tili"<<endl;
                    continue;
                }
                if(tmp->get()==K)                                                                           //杀
                {
                    if(shouyao==get_next()&&shouyao->ifalive())
                    {
                        if(!usedsha||pai.have_z())
                        {
                            pai.del(tmp);
                            usedsha=true;
                            if(get_type()!=MP&&get_csf()<2)
                            {
                                if(shouyao->get_type()==FP)
                                    set_csf(2);
                                else
                                    set_csf(3);
                                recal_all();
                            }
                            if(!shouyao->pai.try_use_d())
                                shouyao->hurt(this);
//                          else
//                              cerr<<"\t"<<shouyao->get_id()<<" lose D now have ";shouyao->pai.print_all(stderr);
                            pai.reset_now();flag=false;
                            if(ans||(!ifalive()))
                                return ;
                        }
                    }
                }
                if(tmp->get()==Z)
                {
                    pai.del(tmp);
                    pai.add_z();
                    pai.reset_now();flag=false;
                }
                if(tmp->get()==F)                                                                           //决斗
                {
                    if(shouyao==NULL)                                                                       //没有攻击目标
                        continue;
//                  cerr<<"shouyao="<<shouyao->get_id()<<endl;
                    if(!shouyao->ifalive())
                        continue;
                    pai.del(tmp);
                    pig_class* tmp=shouyao;                 
                    if(get_type()==FP)
                        tmp=get_mp();
                    pig_class* buf=tmp;
                    if(get_type()!=MP&&get_csf()<2)
                    {
                        if(buf->get_type()==3)
                            set_csf(2);
                        else
                            set_csf(3);
                        recal_all();
                    }
                    if(buf->get_type()==1||buf->get_csf()>=2)
                    {
                        if(buf->get_type()==1||buf->get_csf()==2)
                        {
                            if(start_wx_circle(this,0))
                            {
                                pai.reset_now();flag=false;
                                if(ans||(!ifalive()))
                                    return ;
                                continue ;
                            }
                        }
                        else
                        {
                            if(start_wx_circle(this,1))
                            {
                                pai.reset_now();flag=false;
                                if(ans||(!ifalive()))
                                    return ;
                                continue ;
                            }
                        }
                    }
                    if(get_type()==MP&&tmp->get_type()==ZP)
                        tmp->hurt(this);
                    else
                    {
                        while(1)
                        {
                            if(!tmp->pai.try_use_k())
                            {
                                tmp->hurt(this);
                                break ;
                            }
                            if(!pai.try_use_k())
                            {
                                hurt(tmp);
                                break ;
                            }
                        }
                    }
                    pai.reset_now();flag=false;
                    if(ans||(!ifalive()))
                        return ;
                }
                if(tmp->get()==N)                                                                       //南猪入侵
                {
                    pai.del(tmp);
                    pig_class* buf=get_next();//从下一只猪开始
                    while(buf!=this)//不是这个猪
                    {
//                      cerr<<"\t"<<buf->get_id()<<" csf="<<buf->get_csf()<<endl;
                        if(buf->get_type()==MP||buf->get_csf()>=2)
                        {
                            if(buf->get_type()==MP||buf->get_csf()==2)
                            {
                                if(start_wx_circle(this,0))
                                {
//                                  cerr<<"\t"<<buf->get_id()<<" lose J now have ";buf->pai.print_all(stderr);
                                    buf=buf->get_next();
                                    continue;
                                }
                            }
                            else
                            {
                                if(start_wx_circle(this,1))
                                {
//                                  cerr<<"\t"<<buf->get_id()<<" lose J now have ";buf->pai.print_all(stderr);
                                    buf=buf->get_next();
                                    continue;
                                }
                            }
                        }
                        if(!buf->pai.try_use_k())
                        {
                            buf->hurt(this);
                            if(ans)
                                return;
                            if(buf==get_mp()&&get_csf()==0)
                            {
                                set_csf(1);
                                recal_all();
                            }
                        }
                        else
                        {
//                          cerr<<"\t"<<buf->get_id()<<" lose K now have ";buf->pai.print_all(stderr);
                        }
                        buf=buf->get_next();
                    }
                    pai.reset_now();flag=false;
                    if(ans)
                        return ;
                    continue;
                }
                if(tmp->get()==W)                                                                   //万箭齐发
                {
                    pai.del(tmp);
                    pig_class* buf=get_next();//从下一只猪开始                 
                    while(buf!=this)//不是这个猪
                    {
//                      cerr<<"\t"<<buf->get_id()<<" csf="<<buf->get_csf()<<" type="<<buf->get_type()<<endl;
                        if(buf->get_type()==MP||buf->get_csf()>=2)
                        {
                            if(buf->get_type()==MP||buf->get_csf()==2)
                            {
                                if(start_wx_circle(this,0))
                                {
//                                  cerr<<"\t"<<buf->get_id()<<" lose J now have ";buf->pai.print_all(stderr);
                                    buf=buf->get_next();
                                    continue;
                                }
                            }
                            else
                            {
                                if(start_wx_circle(this,1))
                                {
//                                  cerr<<"\t"<<buf->get_id()<<" lose J now have ";buf->pai.print_all(stderr);                                  
                                    buf=buf->get_next();
                                    continue;
                                }
                            }
                        }
                        if(!buf->pai.try_use_d())
                        {
                            buf->hurt(this);
                            if(ans)
                                return;
                            if(buf==get_mp()&&get_csf()==0)
                            {
                                set_csf(1);
                                recal_all();
                            }
                        }
                        else
                        {
//                          cerr<<"\t"<<buf->get_id()<<" lose D now have ";buf->pai.print_all(stderr);
                        }
                        buf=buf->get_next();
                    }
                    pai.reset_now();flag=false;
                    if(ans)
                        return ;
                }
            }
        }
};
pig_class pig[MAXN];
void recal_all()
{
    pig_class* x=&pig[1];
    do
    {
        x->recal();
        x=x->get_next();
    }   
    while(x!=&pig[1]);
}
pig_class* get_mp()
{
    return &pig[1];
}
bool check_MP_alive()
{
    return pig[1].ifalive();
}
bool start_wx_circle(pig_class * start,bool y_is_fan)
{
    bool st=y_is_fan;
    pig_class *lastdachu=start,*x=start;
    if(y_is_fan==(x->get_type()==FP))
    {
        if(x->pai.try_use_j())
        {
            lastdachu=x;
            y_is_fan^=1;
            if(x->get_csf()<=2)
            {
//              cerr<<"\tset "<<x->get_id()<<" csf to "<<3-y_is_fan<<endl;
                x->set_csf(3-y_is_fan);
                recal_all();
            }
        }
    }
    x=x->get_next();
    while(x!=lastdachu)
    {
        if(y_is_fan==(x->get_type()==3))
        {
            if(x->pai.try_use_j())
            {
                lastdachu=x;
                y_is_fan^=1;
                if(x->get_csf()<=2)
                {
//                  cerr<<"\tset "<<x->get_id()<<" csf to "<<3-y_is_fan<<endl;
                    x->set_csf(3-y_is_fan);
                    recal_all();
                }
            }
        }
        x=x->get_next();
    }
    return (st!=y_is_fan);
}
int main()
{
    freopen("2482.in","r",stdin);
//  freopen("2482.out","w",stdout);
//  freopen("2482.err","w",stderr);
    n=read(),m=read();
    for(int i=1;i<=n;i++)
    {
        pig[i].set_id(i);
        pig[i].set_pro(&pig[i-1]);
        pig[i].set_next(&pig[i+1]);
        pig[i].set_type(readtype());
        pig[i].pai.add(readpai());
        pig[i].pai.add(readpai());
        pig[i].pai.add(readpai());
        pig[i].pai.add(readpai());
//      pig[i].pai.print_all(stderr);
    }
    pig[1].set_pro(&pig[n]);
    pig[n].set_next(&pig[1]);
    recal_all();
    for(int i=0;i<m;i++)
        all_pai.add(readpai());
    pig_class *pig_now=&pig[1];
    while(!ans)
    {
        pig_now->round();
        pig_now->pai.reset_now();
        pig_now=pig_now->get_next();
    }
    if(ans==MPWIN)
        puts("MP");
    else
        puts("FP");
    for(int i=1;i<=n;i++)
        if(!pig[i].ifalive())
            puts("DEAD");
        else
        {
//          puts("ALIVE");
            pig[i].pai.print_all(stdout);
        }
    fclose(stdin);
    fclose(stdout);
    return 0;
}

提示与踩过的坑

几个要点提示吧

  1. 先看题,最好把题背过再开始写
  2. 如果可能,把你的显示器竖起来,因为这题代码是在太长了,鼠标一滚就找不着了

最难也是最重要的就是考虑所有情况,并进行操作,以及代码不要写挂

罗列一下我踩过的坑

  1. 读不进来牌
  2. 主猪错误干掉忠猪时清空牌没清干净
  3. 各种特判细节
  4. 不停使用同一张牌
  5. 牌堆被错误抽空
  6. 数组开小23333我交了好几遍才发现RE是因为这个
  7. 改错代码"南猪入侵"和"万箭齐发"两段代码非常像
  8. 在错误的时装备"猪哥连弩"

最后给出楼下dalao给出的小样例的答案

err是我的代码从stderr数据流输出的debug信息,可以很好地理解猪干了啥

比如在 x use N后出现了y lose K now have zzz x hurt k tili:a表示x发起南猪入侵后 y通过遗弃K避免掉血,还有zzz个牌

而k比较惨,被干了,还有a个血

k die by s是k被s干死了

对着代码就可以理解猪的前世今生,我觉得这种方法比单纯看着数据讲好理解

先给出的是样例,及答案,及err

data:
3 10
MP D D F F
ZP N N N D
FP J J J J
F F D D J J F F K D
ans:
FP
DEAD
DEAD
J J J J J J D
err:
D D F F
N N N D
J J J J
1 have D D F F F F
    1use D
    1use D
    1use F
    1use F
    1use F
    1use F
2 have N N N D D D
    2use N
    2 hurt 3 tili:3
    2 hurt 1 tili:3
    2use N
    2 hurt 3 tili:2
    2 hurt 1 tili:2
    2use N
    2 hurt 3 tili:1
    2 hurt 1 tili:1
    2use D
    2use D
    2use D
3 have J J J J J J
    3use J
    3use J
    3use J
    3use J
    3use J
    3use J
1 have D D F F F F F F
    1use D
    1use D
    1use F
shouyao=2
    1 hurt 2 tili:3
    1use D
    1use D
    1use F
shouyao=2
    1 hurt 2 tili:2
    1use D
    1use D
    1use F
shouyao=2
    1 hurt 2 tili:1
    1use D
    1use D
    1use F
shouyao=2
    2 die by 1
    MP lose all pai
3 have J J J J J J K D
    3use J
    3use J
    3use J
    3use J
    3use J
    3use J
    3use K
    1 die by 3

最后给出楼下dalao给出的小样例的答案

data:
3 4  
MP J J K N   
ZP J D K W   
FP P N P K   
J J K W 

ans:
MP
K
K
DEAD

err:
J J K N
J D K W
P N P K
1 have J J K N J J
    1use J
    1use J
    1use K
    1use N
    2 lose K now have J D W
    3 lose K now have P N P
    1use J
    1use J
    1use K
    1use J
    1use J
2 have J D W K W
    2use J
    2use D
    2use W
    2 hurt 3 tili:3
    set 2 csf to 2
    1 lose J now have J J K J J
    2use D
    2use K
    2use W
    2 hurt 3 tili:2
    set 1 csf to 2
    1 lose J now have J K J J
    2use D
    2use K
3 have P N P W W
    3use P
    3have 3 tili
    3use N
    set 1 csf to 2
    1 lose J now have K J J
    set 1 csf to 2
    2 lose J now have D K
    3use P
    3have 4 tili
    3use W
    set 1 csf to 2
    1 lose J now have K
    2 lose D now have K
    3use W
    3 hurt 1 tili:3
    3 hurt 2 tili:3
1 have K W W
    1use K
    1use W
    1 hurt 2 tili:2
    1 hurt 3 tili:3
    1use K
    1use W
    1 hurt 2 tili:1
    1 hurt 3 tili:2
    1use K
2 have K W W
    2use K
    2use W
    2 hurt 3 tili:1
    2 hurt 1 tili:2
    2use K
    2use W
    3 die by 2
data:
3 1  
MP D N F K  
ZP F W F N  
FP D N N D  
K  
ans:
MP
K
F K K
DEAD
err:
D N F K
F W F N
D N N D
1 have D N F K K K
    1use D
    1use N
    1 hurt 2 tili:3
    1 hurt 3 tili:3
    1use D
    1use F
    1use K
    1use K
    1use K
2 have F W F N K K
    2use F
    2use W
    3 lose D now have N N D
    1 lose D now have F K K K
    2use F
    2use F
    2use N
    2 hurt 3 tili:2
    1 lose K now have F K K
    2use F
    2use F
    2use K
    2use K
3 have N N D K K
    3use N
    1 lose K now have F K
    2 lose K now have F F K
    3use N
    1 lose K now have F
    2 lose K now have F F
    3use D
    3use K
    3 hurt 1 tili:3
F
    3use D
    3use K
1 have F K K
    1use F
shouyao=3
    1 hurt 3 tili:1
    1use K
2 have F F K K
    2use F
shouyao=3
    3 die by 2
data:
5 10  
MP W D F K   
ZP N N D D   
FP F W W K   
ZP K K N D   
FP K D P W   
J K W K D N N K J N
ans:
MP
F N
D
DEAD

DEAD
err:
W D F K
N N D D
F W W K
K K N D
K D P W
1 have W D F K J K
    1use W
    2 lose D now have N N D
    1 hurt 3 tili:3
    4 lose D now have K K N
    5 lose D now have K P W
    1use D
    1use F
    1use K
    1use J
    1use K
2 have N N D W K
    2use N
    3 lose K now have F W W
    4 lose K now have K N
    5 lose K now have P W
    set 1 csf to 2
    1 lose J now have D F K K
    2use N
    2 hurt 3 tili:2
    4 lose K now have N
    2 hurt 5 tili:3
    1 lose K now have D F K
    2use D
    2use W
    2 hurt 3 tili:1
    2 hurt 4 tili:3
    2 hurt 5 tili:2
    1 lose D now have F K
    2use D
    2use K
3 have F W W D N
    3use F
shouyao=1
    3 die by 1
F
    1 get 3 pai haveF N K J
4 have N N N
    4use N
    4 hurt 5 tili:1
    set 1 csf to 2
    1 lose J now have F N K
    2 lose K now have D
    4use N
eat tao
    4 hurt 5 tili:1
    1 lose K now have F N
    4 hurt 2 tili:3
    4use N
    5 die by 4
data:
3 10  
MP W D J W   
ZP J P D N   
FP N D F F   
J D N N F J J D K W 
ans:
MP
D J D

DEAD

err:
W D J W
J P D N
N D F F
1 have W D J W J D
    1use W
    2 lose D now have J P N
    3 lose D now have N F F
    1use D
    1use J
    1use W
    1 hurt 2 tili:3
    1 hurt 3 tili:3
    1use D
    1use J
    1use J
    1use D
2 have J P N N N
    2use J
    2use P
    2have 4 tili
    2use J
    2use N
    2 hurt 3 tili:2
    set 2 csf to 2
    1 lose J now have D J J D
    2use N
    2 hurt 3 tili:1
    set 1 csf to 2
    1 lose J now have D J D
    2use N
    3 die by 2
data:
3 6
MP W J J D
FP N F F K
ZP J J F F
P P K K F W
ans:
MP
P W
DEAD
DEAD

err:
W J J D
N F F K
J J F F
1 have W J J D P P
    1use W
    1 hurt 2 tili:3
    1 hurt 3 tili:3
    1use J
    1use J
    1use D
    1use P
    1use P
2 have N F F K K K
    2use N
    2 hurt 3 tili:2
    set 3 csf to 2
    1 lose J now have J J D P P
    2use F
shouyao=3
    set 3 csf to 2
    2use F
shouyao=3
    set 1 csf to 2
    2use K
    2 hurt 3 tili:1
F F
    2use K
    2use K
3 have F F F W
    3use F
shouyao=2
    3 die by 2
1 have J D P P W W
    1use J
    1use D
    1use P
    1use P
    1use W
    1 hurt 2 tili:2
    1use J
    1use D
    1use P
    1use P
    1use W
    1 hurt 2 tili:1
    1use J
    1use D
    1use P
    1use P
2 have K W W
    2use K
    1 lose D now have J P P
    2use W
    set 1 csf to 2
    1 lose J now have P P
    2use W
    2 hurt 1 tili:3
1 have P P W W
    1use P
    1have 4 tili
    1use P
    1use W
    2 die by 1