题解 P5380 【[THUPC2019]鸭棋】

· · 题解

距离CSP还有10天整的时候,发现自己的算法能力已经崩溃了,百般无奈之下开刷黑模拟,于是在三天之后有了这篇题解

我们先整理一下题目大意:

1、这是一道模拟,模拟一种神奇的棋类游戏

2、棋盘和棋子题目已给出,记得多看几遍(其中鸭的移动方式更是需要好好理解)

3、输入是一堆操作,把(a,b)上的棋移到(c,d)上

4、输出分两种:不合法输出"Invalid command",合法则输出移动的棋,被吃的棋,是否形成将军,游戏是否结束

题意梳理完毕,那我们开始思索解决这道题的方法

1、用二维数组存储地图,用数字代替每一种棋(其实用字符也行,但比较麻烦)

2、移动步骤

3、判断将军

4、输出结果

一道模拟题本来没有什么难度,但是为什么也能排成黑题呢?

1、 每次移动的的时候记得将原来棋子所在的位置清零,并处理它要去的地方

2、注意处理红蓝关系的转换,以及棋盘的边界问题(被卡一次)

3、复制粘贴的时候记得进行彻底的修改,要不然这道题都打完了再去找非常痛苦(被卡三次,总计时间一天)

4、王被抓了以后判断游戏结束,但同时也要记录是哪个王被抓了(被卡一次)

5、每一次移动棋子的时候有很多的限制条件,其中马、象、鸭注意撇腿,车注意中间不能有子(马、鸭、车各被卡了一次)

6、这种大模拟一次写过很难,所以必定调试,注意有一些多余的不该出现的东西要删除(为此CE一次)

那我们开始分析代码吧:

inline void init()          //初始化棋盘 
{
    mapp[0][4]=1,mapp[9][4]=11;
    mapp[0][3]=2,mapp[0][5]=2,mapp[9][3]=12,mapp[9][5]=12;
    mapp[0][2]=3,mapp[0][6]=3,mapp[9][2]=13,mapp[9][6]=13;
    mapp[0][1]=4,mapp[0][7]=4,mapp[9][1]=14,mapp[9][7]=14;
    mapp[0][0]=5,mapp[0][8]=5,mapp[9][0]=15,mapp[9][8]=15;
    mapp[2][0]=6,mapp[2][8]=6,mapp[7][0]=16,mapp[7][8]=16;
    mapp[3][0]=7,mapp[3][2]=7,mapp[3][4]=7,mapp[3][6]=7,mapp[3][8]=7;
    mapp[6][0]=17,mapp[6][2]=17,mapp[6][4]=17,mapp[6][6]=17,mapp[6][8]=17;
}

主函数其实只需包含几个分函数

int main()
{
    init();

    scanf("%d",&Q);

    for(register int i=1;i<=Q;i++)
    {
        scanf("%d%d%d%d",&a,&b,&c,&d);  //读入

        if(capture) {puts("Invalid command");continue;} //如果游戏已结束,那后续操作都不合法

        initmove(); //初始化移动
        move();     //移动

        if(flagout) continue;   //如果移动中不合法则继续(输出在函数中判断)

        check();    //检查是否将军

        print();

        if(turn==0) turn=1; //转换红蓝方
        else turn=0;
    }

    return 0;
}

初始化:

inline void initmove()      // 初始化 move() 
{
    gai=0;
    flagout=0;
    extra=0;
    capture=0;
    jiang=0;
}

移动

#define out {flagout=1;puts("Invalid command");return;}
#define bounce (a>=0&&a<=9&&b>=0&&b<=8&&c>=0&&c<=9&&d>=0&&d<=8)

其中out是如果输入不合法,标记,输出,返回

bounce是确保起点终点都在边界之内

if(turn==1) extra=10;   //因为我用十位来判断红蓝方,所以蓝方则加十
bool fang(bool turn)        // 是哪一方在动 & bounce
{
    if(turn==0) return (mapp[c][d]==0||mapp[c][d]>10);
    else return (mapp[c][d]==0||mapp[c][d]<10);
}
void lose(int c,int d)      //判断吞兵 
{
    if(mapp[c][d]==1) capture=1,gai=1;          //王被吃了标记
    else if(mapp[c][d]==11) capture=2,gai=11;
    else if(mapp[c][d]>10) gai=mapp[c][d],lan--;    //标记被吃的棋
    else if(mapp[c][d]>0) gai=mapp[c][d],hong--;    //hong和lan用来计数,但发现其实没有什么用
}
void exchange(int e,int extra)
{
    mapp[a][b]=0,mapp[c][d]=e+extra;
    which=e+extra;
}

该放表了

inline void move()
{
    //条件 :符合该棋的移动 路上||终点无棋 终点敌方? 没越界

    if(turn==1) extra=10;

    if(mapp[a][b]==1+extra)
    {
        if(bounce==0) out       //前面提到 边界
        if(c-a==1&&b==d&&fang(turn))    {lose(c,d);exchange(1,extra);return;}   //符合移动规则和移动方,则判断吃子和移动
        if(a-c==1&&b==d&&fang(turn)) {lose(c,d);exchange(1,extra);return;}
        if(a==c&&b-d==1&&fang(turn)) {lose(c,d);exchange(1,extra);return;}
        if(a==c&&d-b==1&&fang(turn)) {lose(c,d);exchange(1,extra);return;}
        out
    }

    if(mapp[a][b]==2+extra)
    {
        if(bounce==0) out
        if(c-a==1&&b-d==1&&fang(turn)) {lose(c,d);exchange(2,extra);return;}
        if(a-c==1&&b-d==1&&fang(turn)) {lose(c,d);exchange(2,extra);return;}
        if(c-a==1&&d-b==1&&fang(turn)) {lose(c,d);exchange(2,extra);return;}
        if(a-c==1&&d-b==1&&fang(turn)) {lose(c,d);exchange(2,extra);return;}
        out
    }

    if(mapp[a][b]==3+extra)
    {
        if(bounce==0) out
        if(c==a+2&&d==b+2&&fang(turn)&&mapp[a+1][b+1]==0) {lose(c,d);exchange(3,extra);return;}
        if(c==a+2&&d==b-2&&fang(turn)&&mapp[a+1][b-1]==0) {lose(c,d);exchange(3,extra);return;}
        if(c==a-2&&d==b+2&&fang(turn)&&mapp[a-1][b+1]==0) {lose(c,d);exchange(3,extra);return;}
        if(c==a-2&&d==b-2&&fang(turn)&&mapp[a-1][b-1]==0) {lose(c,d);exchange(3,extra);return;}
        out
    }

    if(mapp[a][b]==4+extra)
    {
        if(bounce==0) out
        if(c-a==2&&d-b==1&&fang(turn)&&mapp[a+1][b]==0) {lose(c,d);exchange(4,extra);return;}
        if(c-a==1&&d-b==2&&fang(turn)&&mapp[a][b+1]==0) {lose(c,d);exchange(4,extra);return;}
        if(c-a==-1&&d-b==2&&fang(turn)&&mapp[a][b+1]==0) {lose(c,d);exchange(4,extra);return;}
        if(c-a==-2&&d-b==1&&fang(turn)&&mapp[a-1][b]==0) {lose(c,d);exchange(4,extra);return;}
        if(c-a==-2&&d-b==-1&&fang(turn)&&mapp[a-1][b]==0) {lose(c,d);exchange(4,extra);return;}
        if(c-a==-1&&d-b==-2&&fang(turn)&&mapp[a][b-1]==0) {lose(c,d);exchange(4,extra);return;}
        if(c-a==1&&d-b==-2&&fang(turn)&&mapp[a][b-1]==0) {lose(c,d);exchange(4,extra);return;}
        if(c-a==2&&d-b==-1&&fang(turn)&&mapp[a+1][b]==0) {lose(c,d);exchange(4,extra);return;}
        out
    }

    if(mapp[a][b]==5+extra)
    {
        if(bounce==0) out
        if(a==c)
        {   
            if(d>b)
            {
                for(register int i=b+1;i<d;i++) if(mapp[a][i]) out                  //有障碍 
                if(fang(turn)) {lose(c,d);exchange(5,extra);return;}            //判断吃,更新 
            }

            else if(d<b)
            {
                for(register int i=b-1;i>d;i--) if(mapp[a][i]) out
                if(fang(turn)) {lose(c,d);exchange(5,extra);return;}
            }

            else out
        }

        else if(b==d)
        {
            if(c>a)
            {
                for(register int i=a+1;i<c;i++) 
                if(mapp[i][b]) out
                if(fang(turn)) {lose(c,d);exchange(5,extra);return;}
            }

            else if(c<a)
            {
                for(register int i=a-1;i>c+1;i--)
                if(mapp[i][b]) out
                if(fang(turn)) {lose(c,d);exchange(5,extra);return;}
            }

            else out
        }

        else out
    }

    if(mapp[a][b]==6+extra)     //这里一定要仔细。。。
    {
        if(bounce==0) out
        if(c-a==2&&d-b==3&&fang(turn)&&mapp[a][b+1]==0&&mapp[a+1][b+2]==0) {lose(c,d);exchange(6,extra);return;}
        if(c-a==3&&d-b==2&&fang(turn)&&mapp[a+1][b]==0&&mapp[a+2][b+1]==0) {lose(c,d);exchange(6,extra);return;}
        if(c-a==-2&&d-b==3&&fang(turn)&&mapp[a][b+1]==0&&mapp[a-1][b+2]==0) {lose(c,d);exchange(6,extra);return;}
        if(c-a==-3&&d-b==2&&fang(turn)&&mapp[a-1][b]==0&&mapp[a-2][b+1]==0) {lose(c,d);exchange(6,extra);return;}
        if(c-a==2&&d-b==-3&&fang(turn)&&mapp[a][b-1]==0&&mapp[a+1][b-2]==0) {lose(c,d);exchange(6,extra);return;}
        if(c-a==3&&d-b==-2&&fang(turn)&&mapp[a+1][b]==0&&mapp[a+2][b-1]==0) {lose(c,d);exchange(6,extra);return;}
        if(c-a==-2&&d-b==-3&&fang(turn)&&mapp[a][b-1]==0&&mapp[a-1][b-2]==0) {lose(c,d);exchange(6,extra);return;}
        if(c-a==-3&&d-b==-2&&fang(turn)&&mapp[a-1][b]==0&&mapp[a-2][b-1]==0) {lose(c,d);exchange(6,extra);return;}
        out
    }

    if(mapp[a][b]==7+extra)
    {
        if(bounce==0) out
        if(c-a==1&&b==d&&fang(turn)) {lose(c,d);exchange(7,extra);return;}
        if(a-c==1&&b==d&&fang(turn)) {lose(c,d);exchange(7,extra);return;}
        if(a==c&&b-d==1&&fang(turn)) {lose(c,d);exchange(7,extra);return;}
        if(a==c&&d-b==1&&fang(turn)) {lose(c,d);exchange(7,extra);return;}
        if(c-a==1&&b-d==1&&fang(turn)) {lose(c,d);exchange(7,extra);return;}
        if(a-c==1&&b-d==1&&fang(turn)) {lose(c,d);exchange(7,extra);return;}
        if(c-a==1&&d-b==1&&fang(turn)) {lose(c,d);exchange(7,extra);return;}
        if(a-c==1&&d-b==1&&fang(turn)) {lose(c,d);exchange(7,extra);return;}
        out
    }

    out
}

接下来是判断将军

inline void check()         // 检查将军 
{
    for(register int i=0;i<=9;i++)
    {
        for(register int j=0;j<=8;j++)      //暴力枚举每一个点
        {
            if(mapp[i][j]==0) continue;

            checkmate(i,j);                 //有棋则搜

            if(jiang) return;               //如果搜到了也就没必要继续了
        }
    }
}
#define checkok {jiang=1;return;}   //符合将军条件则标记,返回

放表:

inline void checkmate(int p,int q)
{
    if(mapp[p][q]>10) checkturn=1,checkextra=10;    //checkturn是这颗棋的目标,checkextra和move中的extra同理
    else checkturn=11,checkextra=0;

    if(mapp[p][q]==1+checkextra)
    {
        if(mapp[p+1][q]==checkturn&&0<=p+1&&p+1<=9&&0<=q&&q<=8) checkok     //一定要判断边界
        if(mapp[p-1][q]==checkturn&&0<=p-1&&p-1<=9&&0<=q&&q<=8) checkok     //虽然理论上不判断也可以
        if(mapp[p][q+1]==checkturn&&0<=p&&p<=9&&0<=q+1&&q+1<=8) checkok     //因为边界之外的棋不会有目标编号
        if(mapp[p][q-1]==checkturn&&0<=p&&p<=9&&0<=q-1&&q-1<=8) checkok     //但是我没判断就是死了,所以。。。
    }

    if(mapp[p][q]==2+checkextra)
    {
        if(mapp[p+1][q+1]==checkturn&&0<=p+1&&p+1<=9&&0<=q+1&&q+1<=8) checkok
        if(mapp[p-1][q+1]==checkturn&&0<=p-1&&p-1<=9&&0<=q+1&&q+1<=8) checkok
        if(mapp[p+1][q-1]==checkturn&&0<=p+1&&p+1<=9&&0<=q-1&&q-1<=8) checkok
        if(mapp[p-1][q-1]==checkturn&&0<=p-1&&p-1<=9&&0<=q-1&&q-1<=8) checkok
    }

    if(mapp[p][q]==3+checkextra)
    {
        if(mapp[p+2][q+2]==checkturn&&mapp[p+1][q+1]==0&&0<=p+2&&p+2<=9&&0<=q+2&&q+2<=8) checkok
        if(mapp[p-2][q+2]==checkturn&&mapp[p-1][q+1]==0&&0<=p-2&&p-2<=9&&0<=q+2&&q+2<=8) checkok
        if(mapp[p+2][q-2]==checkturn&&mapp[p+1][q-1]==0&&0<=p+2&&p+2<=9&&0<=q-2&&q-2<=8) checkok
        if(mapp[p-2][q-2]==checkturn&&mapp[p-1][q-1]==0&&0<=p-2&&p-2<=9&&0<=q-2&&q-2<=8) checkok
    }

    if(mapp[p][q]==4+checkextra)
    {
        if(mapp[p+1][q+2]==checkturn&&mapp[p][q+1]==0&&0<=p+1&&p+1<=9&&0<=q+2&&q+2<=8) checkok
        if(mapp[p+2][q+1]==checkturn&&mapp[p+1][q]==0&&0<=p+2&&p+2<=9&&0<=q+1&&q+1<=8) checkok
        if(mapp[p+2][q-1]==checkturn&&mapp[p+1][q]==0&&0<=p+2&&p+2<=9&&0<=q-1&&q-1<=8) checkok
        if(mapp[p+1][q-2]==checkturn&&mapp[p][q-1]==0&&0<=p+1&&p+1<=9&&0<=q-2&&q-2<=8) checkok
        if(mapp[p-1][q-2]==checkturn&&mapp[p][q-1]==0&&0<=p-1&&p-1<=9&&0<=q-2&&q-2<=8) checkok
        if(mapp[p-2][q-1]==checkturn&&mapp[p-1][q]==0&&0<=p-2&&p-2<=9&&0<=q-1&&q-1<=8) checkok
        if(mapp[p-2][q+1]==checkturn&&mapp[p-1][q]==0&&0<=p-2&&p-2<=9&&0<=q+1&&q+1<=8) checkok
        if(mapp[p-1][q+2]==checkturn&&mapp[p][q+1]==0&&0<=p-1&&p-1<=9&&0<=q+2&&q+2<=8) checkok
    }

    if(mapp[p][q]==5+checkextra)
    {
        for(register int i=p+1;i<=9;i++)
        {
            if(mapp[i][q]==checkturn) checkok
            if(mapp[i][q]!=0) return;
        }

        for(register int i=p-1;i>=0;i--)
        {
            if(mapp[i][q]==checkturn) checkok
            if(mapp[i][q]!=0) return;
        }

        for(register int i=q+1;i<=8;i++)
        {
            if(mapp[p][i]==checkturn) checkok
            if(mapp[p][i]!=0) return;
        }

        for(register int i=q-1;i>=0;i--)
        {
            if(mapp[p][i]==checkturn) checkok
            if(mapp[p][i]!=0) return;
        }
    }

    if(mapp[p][q]==6+checkextra)
    {
        if(mapp[p+2][q+3]==checkturn&&mapp[p][q+1]==0&&mapp[p+1][q+2]==0&&0<=p+2&&p+2<=9&&0<=q+3&&q+3<=8) checkok
        if(mapp[p+3][q+2]==checkturn&&mapp[p+1][q]==0&&mapp[p+2][q+1]==0&&0<=p+3&&p+3<=9&&0<=q+2&&q+2<=8) checkok
        if(mapp[p+3][q-2]==checkturn&&mapp[p+1][q]==0&&mapp[p+2][q-1]==0&&0<=p+3&&p+3<=9&&0<=q-2&&q-2<=8) checkok
        if(mapp[p+2][q-3]==checkturn&&mapp[p][q-1]==0&&mapp[p+1][q-2]==0&&0<=p+2&&p+2<=9&&0<=q-3&&q-3<=8) checkok
        if(mapp[p-2][q-3]==checkturn&&mapp[p][q-1]==0&&mapp[p-1][q-2]==0&&0<=p-2&&p-2<=9&&0<=q-3&&q-3<=8) checkok
        if(mapp[p-3][q-2]==checkturn&&mapp[p-1][q]==0&&mapp[p-2][q-1]==0&&0<=p-3&&p-3<=9&&0<=q-2&&q-2<=8) checkok
        if(mapp[p-3][q+2]==checkturn&&mapp[p-1][q]==0&&mapp[p-2][q+1]==0&&0<=p-3&&p-3<=9&&0<=q+2&&q+2<=8) checkok
        if(mapp[p-2][q+3]==checkturn&&mapp[p][q+1]==0&&mapp[p-1][q+2]==0&&0<=p-2&&p-2<=9&&0<=q+3&&q+3<=8) checkok
    }

    if(mapp[p][q]==7+checkextra)
    {
        if(mapp[p+1][q]==checkturn&&0<=p+1&&p+1<=9&&0<=q&&q<=8) checkok
        if(mapp[p-1][q]==checkturn&&0<=p-1&&p-1<=9&&0<=q&&q<=8) checkok
        if(mapp[p][q+1]==checkturn&&0<=p&&p<=9&&0<=q+1&&q+1<=8) checkok
        if(mapp[p][q-1]==checkturn&&0<=p&&p<=9&&0<=q-1&&q-1<=8) checkok
        if(mapp[p+1][q+1]==checkturn&&0<=p+1&&p+1<=9&&0<=q+1&&q+1<=8) checkok
        if(mapp[p-1][q+1]==checkturn&&0<=p-1&&p-1<=9&&0<=q+1&&q+1<=8) checkok
        if(mapp[p+1][q-1]==checkturn&&0<=p+1&&p+1<=9&&0<=q-1&&q-1<=8) checkok
        if(mapp[p-1][q-1]==checkturn&&0<=p-1&&p-1<=9&&0<=q-1&&q-1<=8) checkok
    }
}

最后我们来输出

inline void print()         //输出 
{
    if(mapp[c][d]==1) printf("red captain;");       //直接判终点的那颗棋
    else if(mapp[c][d]==2) printf("red guard;");        //因为在起点的那颗被移过来了
    else if(mapp[c][d]==3) printf("red elephant;");
    else if(mapp[c][d]==4) printf("red horse;");
    else if(mapp[c][d]==5) printf("red car;");
    else if(mapp[c][d]==6) printf("red duck;");
    else if(mapp[c][d]==7) printf("red soldier;");
    else if(mapp[c][d]==11) printf("blue captain;");
    else if(mapp[c][d]==12) printf("blue guard;");
    else if(mapp[c][d]==13) printf("blue elephant;");
    else if(mapp[c][d]==14) printf("blue horse;");
    else if(mapp[c][d]==15) printf("blue car;");
    else if(mapp[c][d]==16) printf("blue duck;");
    else if(mapp[c][d]==17) printf("blue soldier;");

    if(gai==1) printf("red captain;");      //gai记录被修改的
    else if(gai==2) printf("red guard;");
    else if(gai==3) printf("red elephant;");
    else if(gai==4) printf("red horse;");
    else if(gai==5) printf("red car;");
    else if(gai==6) printf("red duck;");
    else if(gai==7) printf("red soldier;");
    else if(gai==11) printf("blue captain;");
    else if(gai==12) printf("blue guard;");
    else if(gai==13) printf("blue elephant;");
    else if(gai==14) printf("blue horse;");
    else if(gai==15) printf("blue car;");
    else if(gai==16) printf("blue duck;");
    else if(gai==17) printf("blue soldier;");
    else printf("NA;");                     //注意没有的话输出NA

    if(capture==0&&jiang) printf("yes;");
    else printf("no;");

    if(capture) puts("yes");                //注意这里输出没有分号!!!
    else puts("no");
}

于是我们愉快的A掉了这道题

放代码(我提交的时候的代码,内含我写这道题时自己放的注释):

//记得每次移动前加 lose(c,d) 
//注意转换turn 
//注意移动时清空之前的格子 
//复制粘贴时记得进行必要修改 
//注意棋盘的边界 

//check时修改extra
//发现其实extra是turn的10倍,但是懒得改了
//记得captain被抓了也要标记修改了哪颗棋 
//记得动车的时候fang()

#include <bits/stdc++.h>
//#include <windows.h>                                                              //////////////
using namespace std;
#define out {flagout=1;puts("Invalid command");return;}
#define bounce (a>=0&&a<=9&&b>=0&&b<=8&&c>=0&&c<=9&&d>=0&&d<=8)
#define checkok {jiang=1;return;}                                                   //////////

int Q;
int a,b,c,d;
                                                                                            // 全局变量区

int mapp[12][12];                       //列 行 : 如 mapp[4][3]表红方第二个兵 
bool turn=0;        // 红0 蓝1        //王1 士2 象3 马4 车5 鸭6 兵7  红单位,蓝双位

int checkturn;      //记录check的时候对方的王 
int hong=16,lan=16,gai;     //总兵数  被吃兵 
                                                                                            // 红蓝变量区

bool flagout;   //判断是否被out掉 
bool capture=0,jiang=0; // 1为被抓/将军
int extra,checkextra;       // move的时候结果是什么兵的修改
int which;      // move的时候调用的什么兵 
                                                                                            //特殊辅助区 

//int yhong=1,ylan=2,ybai=3;                                                    
//void Color(int a){
//    if(a==1) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED);
//    if(a==2) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_BLUE|FOREGROUND_GREEN);
//    if(a==3) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED);
//}

inline void init()          //初始化棋盘 
{
    mapp[0][4]=1,mapp[9][4]=11;
    mapp[0][3]=2,mapp[0][5]=2,mapp[9][3]=12,mapp[9][5]=12;
    mapp[0][2]=3,mapp[0][6]=3,mapp[9][2]=13,mapp[9][6]=13;
    mapp[0][1]=4,mapp[0][7]=4,mapp[9][1]=14,mapp[9][7]=14;
    mapp[0][0]=5,mapp[0][8]=5,mapp[9][0]=15,mapp[9][8]=15;
    mapp[2][0]=6,mapp[2][8]=6,mapp[7][0]=16,mapp[7][8]=16;
    mapp[3][0]=7,mapp[3][2]=7,mapp[3][4]=7,mapp[3][6]=7,mapp[3][8]=7;
    mapp[6][0]=17,mapp[6][2]=17,mapp[6][4]=17,mapp[6][6]=17,mapp[6][8]=17;
}

void lose(int c,int d)      //判断吞兵 
{
    if(mapp[c][d]==1) capture=1,gai=1;
    else if(mapp[c][d]==11) capture=2,gai=11;
    else if(mapp[c][d]>10) gai=mapp[c][d],lan--;
    else if(mapp[c][d]>0) gai=mapp[c][d],hong--;
}

bool fang(bool turn)        // 是哪一方在动 & bounce
{
    if(turn==0) return (mapp[c][d]==0||mapp[c][d]>10);
    else return (mapp[c][d]==0||mapp[c][d]<10);
}

void exchange(int e,int extra)
{
    mapp[a][b]=0,mapp[c][d]=e+extra;
    which=e+extra;
}

inline void move()
{
    //条件 :符合该棋的移动 路上||终点无棋 终点敌方? 没越界

    if(turn==1) extra=10;

    if(mapp[a][b]==1+extra)
    {
        if(bounce==0) out
        if(c-a==1&&b==d&&fang(turn)) {lose(c,d);exchange(1,extra);return;}
        if(a-c==1&&b==d&&fang(turn)) {lose(c,d);exchange(1,extra);return;}
        if(a==c&&b-d==1&&fang(turn)) {lose(c,d);exchange(1,extra);return;}
        if(a==c&&d-b==1&&fang(turn)) {lose(c,d);exchange(1,extra);return;}
        out
    }

    if(mapp[a][b]==2+extra)
    {
        if(bounce==0) out
        if(c-a==1&&b-d==1&&fang(turn)) {lose(c,d);exchange(2,extra);return;}
        if(a-c==1&&b-d==1&&fang(turn)) {lose(c,d);exchange(2,extra);return;}
        if(c-a==1&&d-b==1&&fang(turn)) {lose(c,d);exchange(2,extra);return;}
        if(a-c==1&&d-b==1&&fang(turn)) {lose(c,d);exchange(2,extra);return;}
        out
    }

    if(mapp[a][b]==3+extra)
    {
        if(bounce==0) out
        if(c==a+2&&d==b+2&&fang(turn)&&mapp[a+1][b+1]==0) {lose(c,d);exchange(3,extra);return;}
        if(c==a+2&&d==b-2&&fang(turn)&&mapp[a+1][b-1]==0) {lose(c,d);exchange(3,extra);return;}
        if(c==a-2&&d==b+2&&fang(turn)&&mapp[a-1][b+1]==0) {lose(c,d);exchange(3,extra);return;}
        if(c==a-2&&d==b-2&&fang(turn)&&mapp[a-1][b-1]==0) {lose(c,d);exchange(3,extra);return;}
        out
    }

    if(mapp[a][b]==4+extra)
    {
        if(bounce==0) out
        if(c-a==2&&d-b==1&&fang(turn)&&mapp[a+1][b]==0) {lose(c,d);exchange(4,extra);return;}
        if(c-a==1&&d-b==2&&fang(turn)&&mapp[a][b+1]==0) {lose(c,d);exchange(4,extra);return;}
        if(c-a==-1&&d-b==2&&fang(turn)&&mapp[a][b+1]==0) {lose(c,d);exchange(4,extra);return;}
        if(c-a==-2&&d-b==1&&fang(turn)&&mapp[a-1][b]==0) {lose(c,d);exchange(4,extra);return;}
        if(c-a==-2&&d-b==-1&&fang(turn)&&mapp[a-1][b]==0) {lose(c,d);exchange(4,extra);return;}
        if(c-a==-1&&d-b==-2&&fang(turn)&&mapp[a][b-1]==0) {lose(c,d);exchange(4,extra);return;}
        if(c-a==1&&d-b==-2&&fang(turn)&&mapp[a][b-1]==0) {lose(c,d);exchange(4,extra);return;}
        if(c-a==2&&d-b==-1&&fang(turn)&&mapp[a+1][b]==0) {lose(c,d);exchange(4,extra);return;}
        out
    }

    if(mapp[a][b]==5+extra)
    {
        if(bounce==0) out
        if(a==c)
        {   
            if(d>b)
            {
                for(register int i=b+1;i<d;i++) if(mapp[a][i]) out                  //有障碍 
                if(fang(turn)) {lose(c,d);exchange(5,extra);return;}            //判断吃,更新 
            }

            else if(d<b)
            {
                for(register int i=b-1;i>d;i--) if(mapp[a][i]) out
                if(fang(turn)) {lose(c,d);exchange(5,extra);return;}
            }

            else out
        }

        else if(b==d)
        {
            if(c>a)
            {
                for(register int i=a+1;i<c;i++) 
                if(mapp[i][b]) out
                if(fang(turn)) {lose(c,d);exchange(5,extra);return;}
            }

            else if(c<a)
            {
                for(register int i=a-1;i>c+1;i--)
                if(mapp[i][b]) out
                if(fang(turn)) {lose(c,d);exchange(5,extra);return;}
            }

            else out
        }

        else out
    }

    if(mapp[a][b]==6+extra)
    {
        if(bounce==0) out
        if(c-a==2&&d-b==3&&fang(turn)&&mapp[a][b+1]==0&&mapp[a+1][b+2]==0) {lose(c,d);exchange(6,extra);return;}
        if(c-a==3&&d-b==2&&fang(turn)&&mapp[a+1][b]==0&&mapp[a+2][b+1]==0) {lose(c,d);exchange(6,extra);return;}
        if(c-a==-2&&d-b==3&&fang(turn)&&mapp[a][b+1]==0&&mapp[a-1][b+2]==0) {lose(c,d);exchange(6,extra);return;}
        if(c-a==-3&&d-b==2&&fang(turn)&&mapp[a-1][b]==0&&mapp[a-2][b+1]==0) {lose(c,d);exchange(6,extra);return;}
        if(c-a==2&&d-b==-3&&fang(turn)&&mapp[a][b-1]==0&&mapp[a+1][b-2]==0) {lose(c,d);exchange(6,extra);return;}
        if(c-a==3&&d-b==-2&&fang(turn)&&mapp[a+1][b]==0&&mapp[a+2][b-1]==0) {lose(c,d);exchange(6,extra);return;}
        if(c-a==-2&&d-b==-3&&fang(turn)&&mapp[a][b-1]==0&&mapp[a-1][b-2]==0) {lose(c,d);exchange(6,extra);return;}
        if(c-a==-3&&d-b==-2&&fang(turn)&&mapp[a-1][b]==0&&mapp[a-2][b-1]==0) {lose(c,d);exchange(6,extra);return;}
        out
    }

    if(mapp[a][b]==7+extra)
    {
        if(bounce==0) out
        if(c-a==1&&b==d&&fang(turn)) {lose(c,d);exchange(7,extra);return;}
        if(a-c==1&&b==d&&fang(turn)) {lose(c,d);exchange(7,extra);return;}
        if(a==c&&b-d==1&&fang(turn)) {lose(c,d);exchange(7,extra);return;}
        if(a==c&&d-b==1&&fang(turn)) {lose(c,d);exchange(7,extra);return;}
        if(c-a==1&&b-d==1&&fang(turn)) {lose(c,d);exchange(7,extra);return;}
        if(a-c==1&&b-d==1&&fang(turn)) {lose(c,d);exchange(7,extra);return;}
        if(c-a==1&&d-b==1&&fang(turn)) {lose(c,d);exchange(7,extra);return;}
        if(a-c==1&&d-b==1&&fang(turn)) {lose(c,d);exchange(7,extra);return;}
        out
    }

    out
}

inline void initmove()      // 初始化 move() 
{
    gai=0;
    flagout=0;
    extra=0;
    capture=0;
    jiang=0;
}

inline void checkmate(int p,int q)
{
    if(mapp[p][q]>10) checkturn=1,checkextra=10;
    else checkturn=11,checkextra=0;

    if(mapp[p][q]==1+checkextra)
    {
        if(mapp[p+1][q]==checkturn&&0<=p+1&&p+1<=9&&0<=q&&q<=8) checkok
        if(mapp[p-1][q]==checkturn&&0<=p-1&&p-1<=9&&0<=q&&q<=8) checkok
        if(mapp[p][q+1]==checkturn&&0<=p&&p<=9&&0<=q+1&&q+1<=8) checkok
        if(mapp[p][q-1]==checkturn&&0<=p&&p<=9&&0<=q-1&&q-1<=8) checkok
    }

    if(mapp[p][q]==2+checkextra)
    {
        if(mapp[p+1][q+1]==checkturn&&0<=p+1&&p+1<=9&&0<=q+1&&q+1<=8) checkok
        if(mapp[p-1][q+1]==checkturn&&0<=p-1&&p-1<=9&&0<=q+1&&q+1<=8) checkok
        if(mapp[p+1][q-1]==checkturn&&0<=p+1&&p+1<=9&&0<=q-1&&q-1<=8) checkok
        if(mapp[p-1][q-1]==checkturn&&0<=p-1&&p-1<=9&&0<=q-1&&q-1<=8) checkok
    }

    if(mapp[p][q]==3+checkextra)
    {
        if(mapp[p+2][q+2]==checkturn&&mapp[p+1][q+1]==0&&0<=p+2&&p+2<=9&&0<=q+2&&q+2<=8) checkok
        if(mapp[p-2][q+2]==checkturn&&mapp[p-1][q+1]==0&&0<=p-2&&p-2<=9&&0<=q+2&&q+2<=8) checkok
        if(mapp[p+2][q-2]==checkturn&&mapp[p+1][q-1]==0&&0<=p+2&&p+2<=9&&0<=q-2&&q-2<=8) checkok
        if(mapp[p-2][q-2]==checkturn&&mapp[p-1][q-1]==0&&0<=p-2&&p-2<=9&&0<=q-2&&q-2<=8) checkok
    }

    if(mapp[p][q]==4+checkextra)
    {
        if(mapp[p+1][q+2]==checkturn&&mapp[p][q+1]==0&&0<=p+1&&p+1<=9&&0<=q+2&&q+2<=8) checkok
        if(mapp[p+2][q+1]==checkturn&&mapp[p+1][q]==0&&0<=p+2&&p+2<=9&&0<=q+1&&q+1<=8) checkok
        if(mapp[p+2][q-1]==checkturn&&mapp[p+1][q]==0&&0<=p+2&&p+2<=9&&0<=q-1&&q-1<=8) checkok
        if(mapp[p+1][q-2]==checkturn&&mapp[p][q-1]==0&&0<=p+1&&p+1<=9&&0<=q-2&&q-2<=8) checkok
        if(mapp[p-1][q-2]==checkturn&&mapp[p][q-1]==0&&0<=p-1&&p-1<=9&&0<=q-2&&q-2<=8) checkok
        if(mapp[p-2][q-1]==checkturn&&mapp[p-1][q]==0&&0<=p-2&&p-2<=9&&0<=q-1&&q-1<=8) checkok
        if(mapp[p-2][q+1]==checkturn&&mapp[p-1][q]==0&&0<=p-2&&p-2<=9&&0<=q+1&&q+1<=8) checkok
        if(mapp[p-1][q+2]==checkturn&&mapp[p][q+1]==0&&0<=p-1&&p-1<=9&&0<=q+2&&q+2<=8) checkok
    }

    if(mapp[p][q]==5+checkextra)
    {
        for(register int i=p+1;i<=9;i++)
        {
            if(mapp[i][q]==checkturn) checkok
            if(mapp[i][q]!=0) return;
        }

        for(register int i=p-1;i>=0;i--)
        {
            if(mapp[i][q]==checkturn) checkok
            if(mapp[i][q]!=0) return;
        }

        for(register int i=q+1;i<=8;i++)
        {
            if(mapp[p][i]==checkturn) checkok
            if(mapp[p][i]!=0) return;
        }

        for(register int i=q-1;i>=0;i--)
        {
            if(mapp[p][i]==checkturn) checkok
            if(mapp[p][i]!=0) return;
        }
    }

    if(mapp[p][q]==6+checkextra)
    {
        if(mapp[p+2][q+3]==checkturn&&mapp[p][q+1]==0&&mapp[p+1][q+2]==0&&0<=p+2&&p+2<=9&&0<=q+3&&q+3<=8) checkok
        if(mapp[p+3][q+2]==checkturn&&mapp[p+1][q]==0&&mapp[p+2][q+1]==0&&0<=p+3&&p+3<=9&&0<=q+2&&q+2<=8) checkok
        if(mapp[p+3][q-2]==checkturn&&mapp[p+1][q]==0&&mapp[p+2][q-1]==0&&0<=p+3&&p+3<=9&&0<=q-2&&q-2<=8) checkok
        if(mapp[p+2][q-3]==checkturn&&mapp[p][q-1]==0&&mapp[p+1][q-2]==0&&0<=p+2&&p+2<=9&&0<=q-3&&q-3<=8) checkok
        if(mapp[p-2][q-3]==checkturn&&mapp[p][q-1]==0&&mapp[p-1][q-2]==0&&0<=p-2&&p-2<=9&&0<=q-3&&q-3<=8) checkok
        if(mapp[p-3][q-2]==checkturn&&mapp[p-1][q]==0&&mapp[p-2][q-1]==0&&0<=p-3&&p-3<=9&&0<=q-2&&q-2<=8) checkok
        if(mapp[p-3][q+2]==checkturn&&mapp[p-1][q]==0&&mapp[p-2][q+1]==0&&0<=p-3&&p-3<=9&&0<=q+2&&q+2<=8) checkok
        if(mapp[p-2][q+3]==checkturn&&mapp[p][q+1]==0&&mapp[p-1][q+2]==0&&0<=p-2&&p-2<=9&&0<=q+3&&q+3<=8) checkok
    }

    if(mapp[p][q]==7+checkextra)
    {
        if(mapp[p+1][q]==checkturn&&0<=p+1&&p+1<=9&&0<=q&&q<=8) checkok
        if(mapp[p-1][q]==checkturn&&0<=p-1&&p-1<=9&&0<=q&&q<=8) checkok
        if(mapp[p][q+1]==checkturn&&0<=p&&p<=9&&0<=q+1&&q+1<=8) checkok
        if(mapp[p][q-1]==checkturn&&0<=p&&p<=9&&0<=q-1&&q-1<=8) checkok
        if(mapp[p+1][q+1]==checkturn&&0<=p+1&&p+1<=9&&0<=q+1&&q+1<=8) checkok
        if(mapp[p-1][q+1]==checkturn&&0<=p-1&&p-1<=9&&0<=q+1&&q+1<=8) checkok
        if(mapp[p+1][q-1]==checkturn&&0<=p+1&&p+1<=9&&0<=q-1&&q-1<=8) checkok
        if(mapp[p-1][q-1]==checkturn&&0<=p-1&&p-1<=9&&0<=q-1&&q-1<=8) checkok
    }
}

inline void check()         // 检查将军 
{
    for(register int i=0;i<=9;i++)
    {
        for(register int j=0;j<=8;j++)
        {
            if(mapp[i][j]==0) continue;

            checkmate(i,j);

            if(jiang) return;
        }
    }
}

inline void print()         //输出 
{
    if(mapp[c][d]==1) printf("red captain;");
    else if(mapp[c][d]==2) printf("red guard;");
    else if(mapp[c][d]==3) printf("red elephant;");
    else if(mapp[c][d]==4) printf("red horse;");
    else if(mapp[c][d]==5) printf("red car;");
    else if(mapp[c][d]==6) printf("red duck;");
    else if(mapp[c][d]==7) printf("red soldier;");
    else if(mapp[c][d]==11) printf("blue captain;");
    else if(mapp[c][d]==12) printf("blue guard;");
    else if(mapp[c][d]==13) printf("blue elephant;");
    else if(mapp[c][d]==14) printf("blue horse;");
    else if(mapp[c][d]==15) printf("blue car;");
    else if(mapp[c][d]==16) printf("blue duck;");
    else if(mapp[c][d]==17) printf("blue soldier;");

    if(gai==1) printf("red captain;");
    else if(gai==2) printf("red guard;");
    else if(gai==3) printf("red elephant;");
    else if(gai==4) printf("red horse;");
    else if(gai==5) printf("red car;");
    else if(gai==6) printf("red duck;");
    else if(gai==7) printf("red soldier;");
    else if(gai==11) printf("blue captain;");
    else if(gai==12) printf("blue guard;");
    else if(gai==13) printf("blue elephant;");
    else if(gai==14) printf("blue horse;");
    else if(gai==15) printf("blue car;");
    else if(gai==16) printf("blue duck;");
    else if(gai==17) printf("blue soldier;");
    else printf("NA;");

    if(capture==0&&jiang) printf("yes;");
    else printf("no;");

    if(capture) puts("yes");
    else puts("no");
}

int main()
{
//  freopen("2test.in","r",stdin);
//  freopen("test.out","w",stdout);

    init();
//  Color(ybai);                    /////
//  int cc=0;

//  for(register int i=9;i>=0;i--)
//  {
//      for(register int j=8;j>=0;j--)
//      {
//          cout<<setw(5)<<mapp[i][j];
//      }
//      puts("");
//  }

    scanf("%d",&Q);

    for(register int i=1;i<=Q;i++)
    {
//      cout<<i<<" ";                   ////

        scanf("%d%d%d%d",&a,&b,&c,&d);

        if(capture) {puts("Invalid command");continue;}

        initmove();
        move();

        if(flagout) continue;

//      if(i<=586) 
//      system("cls");                              /////
//      for(register int i=9;i>=0;i--)
//      {
//          for(register int j=0;j<=8;j++)
//          {
//              if(mapp[i][j]<10&&mapp[i][j]!=0)
//              {
//                  Color(yhong),cout<<setw(5)<<mapp[i][j],Color(ybai);
//              }
//              else if(mapp[i][j]>10)
//              {
//                  Color(ylan),cout<<setw(5)<<mapp[i][j],Color(ybai);
//              }
//              else Color(ybai),cout<<setw(5)<<mapp[i][j];
//          }
//          puts("");
//      }
//      puts(""),puts("");                                          /////

        check();

        print();

        if(turn==0) turn=1;
        else turn=0;

//      if(i>=590) system("pause");
//      if(i>=357) 
    }

    return 0;
}

写题解不易,兹磁一下呗!

\color{white}\texttt{By Possible}