GYM MaratonIME plays Chess 模拟

题目链接

GYM101744D

题解

题意

给出一个棋盘,上面分布着许多棋子,判断能否用自己的任意一个棋子在一步之内吃到指定的对面的棋子。

思路

模拟!
还是有很多可以回味的地方滴。

  1. 输入方面
    1. 可以看出棋盘的[0, 0]位置是在左下角的,为了方便处理我们可以倒着存图;
  2. 读题细节方面
    1. 注意p只能走一步而不是整个对角线;
    2. 骑士的八个方位是不会受到除了出界之外的阻挡的;
    3. 国王可以走八个方位。

代码逻辑:
存储小写字母和大写字母的位置。小写字母会被小写字母阻挡且不能到达该小写字母的位置,也会被碰到的第一个大写字母阻挡但是可以吃掉这个大写字母。通过这个判断每个小写字母所能到达的所有点。之后判断这个集合中是否包含题目给出的点即可。

AC代码

#include <bits/stdc++.h>

using namespace std;

int const N = 10;
typedef pair<int, int> P;
char ch[N][N];
set<P> big, reach, lit;

bool grid(int x, int y) {
    return (x >= 0 && x < 8 && y >= 0 && y < 8) && ((lit.find(P(x, y)) == lit.end()));
}

void JudgeP(int x, int y) {
    int xx = 1, yy = -1;
    int X = x, Y = y;
    x += xx, y += yy;
    if (grid(x, y)) {
        reach.insert(P(x, y));
    }

    x = X, y = Y;
    xx = 1, yy = 1;
    x += xx, y += yy;
    if (grid(x, y)) {
        reach.insert(P(x, y));
    }
}

int f[8][2] = {
        {1,  -2},
        {1,  2},
        {-1, -2},
        {-1, 2},
        {2,  1},
        {2,  -1},
        {-2, 1},
        {-2, -1},
};

void JudgeC(int x, int y) {
    for (auto &i : f) {
        int xx = x + i[0], yy = y + i[1];
        if (grid(xx, yy)) {
            reach.insert(P(xx, yy));
        }
    }
}

void JudgeT(int x, int y) {
    int xo = x, yo = y;

    x -= 1;
    while (grid(x, y)) {
        reach.insert(P(x, y));
        if ((big.find(P(x, y)) != big.end())) {
            break;
        }
        x -= 1;
    }

    x = xo, y = yo;
    y -= 1;
    while (grid(x, y)) {
        reach.insert(P(x, y));
        if ((big.find(P(x, y)) != big.end())) {
            break;
        }
        y -= 1;
    }

    x = xo, y = yo;
    x += 1;
    while (grid(x, y)) {
        reach.insert(P(x, y));
        if ((big.find(P(x, y)) != big.end())) {
            break;
        }
        x += 1;
    }

    x = xo, y = yo;
    y += 1;
    while (grid(x, y)) {
        reach.insert(P(x, y));
        if ((big.find(P(x, y)) != big.end())) {
            break;
        }
        y += 1;
    }
}

void JudgeB(int x, int y) {
    int xx = 1, yy = -1;
    int xo = x, yo = y;
    x += xx, y += yy;
    while (grid(x, y)) {
        reach.insert(P(x, y));
        if ((big.find(P(x, y)) != big.end())) {
            break;
        }
        x += xx, y += yy;
    }

    xx = -1, yy = 1;
    x = xo, y = yo;
    x += xx, y += yy;
    while (grid(x, y)) {
        reach.insert(P(x, y));
        if ((big.find(P(x, y)) != big.end())) {
            break;
        }
        x += xx, y += yy;
    }

    xx = -1, yy = -1;
    x = xo, y = yo;
    x += xx, y += yy;
    while (grid(x, y)) {
        reach.insert(P(x, y));
        if ((big.find(P(x, y)) != big.end())) {
            break;
        }
        x += xx, y += yy;
    }

    xx = 1, yy = 1;
    x = xo, y = yo;
    x += xx, y += yy;
    while (grid(x, y)) {
        reach.insert(P(x, y));
        if ((big.find(P(x, y)) != big.end())) {
            break;
        }
        x += xx, y += yy;
    }
}

void JudgeR(int x, int y) {
    JudgeB(x, y);
    JudgeT(x, y);
}

int ff[8][2] = {
        {1,  0},
        {0,  1},
        {0,  -1},
        {-1, 0},
        {-1, -1},
        {-1, 1},
        {1,  -1},
        {1,  1},
};

void JudgeK(int x, int y) {
    for (auto &i : ff) {
        int xx = x + i[0], yy = y + i[1];
        if (grid(xx, yy)) {
            reach.insert(P(xx, yy));
        }
    }
}

int main() {
    for (int i = 7; i >= 0; i--) {
        scanf("%s", ch[i]);
        for (int j = 0; j < 8; j++) {
            if (ch[i][j] >= 'a' && ch[i][j] <= 'z') lit.insert(P(i, j));
            else if (ch[i][j] != '.') {
                big.insert(P(i, j));
            }
        }
    }
    for (int i = 7; i >= 0; i--) {
        for (int j = 0; j < 8; j++) {
            char chr = ch[i][j];
            switch (chr) {
                case 'p':
                    reach.insert(P(i, j));
                    JudgeP(i, j);
                    break;
                case 'c':
                    JudgeC(i, j);
                    reach.insert(P(i, j));
                    break;
                case 't':
                    JudgeT(i, j);
                    reach.insert(P(i, j));
                    break;
                case 'b':
                    JudgeB(i, j);
                    reach.insert(P(i, j));
                    break;
                case 'r':
                    JudgeR(i, j);
                    reach.insert(P(i, j));
                    break;
                case 'k':
                    JudgeK(i, j);
                    reach.insert(P(i, j));
                    break;
                default:
                    break;
            }
        }
    }
    char tmp[10];
    scanf("%s", tmp);
    int Y = tmp[0] - 'a', X = tmp[1] - '0' - 1;
    if (reach.find(P(X, Y)) != reach.end()) {
        cout << "Sim" << '\n';
    } else cout << "Nao" << '\n';
    return 0;
}

后记

又到了记录憨批时刻的时刻了。

读题读题读题读题!!!!
这个题是真滴让我又一次认识到了读题的重要性啊QAQ
第一次WA:这个时候代码已经大概成形,判断了一下发现棋盘的存储反了QAQ
第二次WA:误以为大小写都可以走
第三次WA:把大写字母和小写字母的处理逻辑混淆成一种,即到不了大写字母的位置。。
第四次WA:在不应该break的地方break了
第五次WA:国王可以走八个方向
第六次WA:卒一次只能走一步,我以为是一整个对角线
大概。。。就这些。。。
本来以为这题给我二十分钟还来得及,结果就很难受QAQ

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值