第四章习题 4-1

考虑一个象棋残局,其中红方有n(2≤n≤7)个棋子,黑方只有一个将。红方除了有一个
帅(G)之外还有3种可能的棋子:车(R),马(H),炮(C),并且需要考虑“蹩马
腿”(如图4-4所示)与将和帅不能照面(将、帅如果同在一条直线上,中间又不隔着任何棋
子的情况下,走子的一方获胜)的规则。
输入所有棋子的位置,保证局面合法并且红方已经将军。你的任务是判断红方是否已经
把黑方将死。关于中国象棋的相关规则请参见原题。

当前局面 红字已经将军 现在轮到黑子下棋 问下一步是不是还是被红子将军 如果是输出yes 如果不是输出no(需要考虑马会被蹩脚的情况)

样例解释如图:

看到这题很快就可以想到 之前的例题追踪电子表格中的单元格(4-5)这题

用哪一题的两种方法应该是都可以解出来的

之前我用的第一种方式解题,发现要写的if有点多,又懒的搞几个数组,然后索性百度了一下别人写的,发现大多数都是根据第二种方式解题 这样我就懒得写这题了 直接就转载别人代码

转载自(转载未经未经博主许可):

https://blog.csdn.net/thudaliangrx/article/details/50700688?locationNum=2&fps=1#t9

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

struct Chess {
    char t; //0, 1, G, R, H, C
    int x, y;
    Chess () {}
    Chess (char t1, int x1, int y1)
    {
        t = t1, x = x1, y = y1;
    }
};

char tab0[11][11], tab[11][11];
Chess gnr;
int n;
Chess pos[8];
int mov[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
int movH[8][2] = {{1, 2}, {-1, 2}, {2, 1}, {2, -1},
    {1, -2}, {-1, -2}, {-2, 1}, {-2, -1}};

bool legal(int x, int y)
{
    return 1 <= x && x <= 3 && 4 <= y && y <= 6;
}

Chess move(Chess p, int i)
{
    Chess p1(p.t, p.x+ mov[i][0], p.y + mov[i][1]);
    if (!legal(p1.x, p1.y)) return Chess('0', 1, 1);
    tab[p1.x][p1.y] = '1';
    tab[p.x][p.y] = '0';
    return p1;
}

int cnt(Chess p1, Chess p2)
{
    int cnt = 0;
    if (p1.x == p2.x) {
        int add = (p1.y < p2.y ? 1 : -1);
        for (int j = p1.y+add; j != p2.y; j += add) {
            if (tab[p1.x][j] != '0') cnt ++;
        }
    }
    else if (p1.y == p2.y) {
        int add = (p1.x < p2.x ? 1 : -1);
        for (int j = p1.x+add; j != p2.x; j += add) {
            if (tab[j][p1.y] != '0') cnt ++;
        }
    } else
        cnt = 10;
    return cnt;
}

bool check()
{
    //true 合法, false 将死
    for (int i = 1; i <= n; i ++) {
        //printf("%c : %d %d %d %d\n", pos[i].t, pos[i].x, pos[i].y, pos[0].x, pos[0].y);
        if (pos[0].x == pos[i].x && pos[0].y == pos[i].y) continue;
        if (pos[i].t == 'G' || pos[i].t == 'R') {
            if (cnt(pos[0], pos[i]) == 0) return false;
        } else if (pos[i].t == 'C') {
            if (cnt(pos[0], pos[i]) == 1) return false;
        } else {
            for (int j = 0; j < 8; j ++) {
                if (pos[i].x + movH[j][0] == pos[0].x
                && pos[i].y + movH[j][1] == pos[0].y
                && tab[pos[i].x + mov[j/2][0]][pos[i].y + mov[j/2][1]] == '0')
                    return false;
            }
        }
    }
    return true;
}

void print()
{
    for (int i = 1; i <= 10; i ++) {
        for (int j = 1; j <= 9; j ++) {
            printf("%c ", tab0[i][j]);
        }
        printf("\n");
    }
}

int main(void)
{
    while (scanf("%d%d%d", &n, &gnr.x, &gnr.y), n || gnr.x || gnr.y) {
        memset(tab0, '0', sizeof(tab0));
        tab0[gnr.x][gnr.y] = '1';
        for (int i = 1; i <= n; i ++) {
            char type[2];
            scanf("%s%d%d", type, &pos[i].x, &pos[i].y);
            pos[i].t = type[0];
            tab0[pos[i].x][pos[i].y] = pos[i].t;
        }
        //print();

        bool res = true;
        for (int i = 0; i < 4; i ++) {
            memcpy(tab, tab0, sizeof(tab0));
            pos[0].x = gnr.x+ mov[i][0];
            pos[0].y = gnr.y + mov[i][1];
            if (!legal(pos[0].x, pos[0].y)) continue;
            tab[pos[0].x][pos[0].y] = '1';
            tab[gnr.x][gnr.y] = '0';
            if (check()) { res = false; break; }
        }

        if (res) puts("YES");
        else puts("NO");
    }

    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值