题解:P11878 城堡中的皇后

· · 题解

原题链接

分析

本题为大模拟,只要有耐心就能过。

其实,题目已经把绝大多数解题需要的信息告诉我们了,只需按题意模拟即可。

题目分析虽不难,但码量极大,一定要耐心的敲完!

Code

#include <bits/stdc++.h>
using namespace std;
bool at(int kr, int kc, bool iw, const vector<string>& b){ // 判断是否有一方被将军
    // 判断此时国王是否受兵攻击
    if(iw){
        int r = kr - 1, c = kc - 1;
        if(r >= 0 && c >= 0 && b[r][c]=='p') return true;
        r = kr - 1, c = kc + 1;
        if(r >= 0 && c < 8 && b[r][c]=='p') return true;
    }
    else{
        int r = kr + 1, c = kc - 1;
        if(r < 8 && c >= 0 && b[r][c]=='P') return true;
        r = kr + 1, c = kc + 1;
        if(r < 8 && c < 8 && b[r][c]=='P') return true;
    }
    // 判断国王此时是否受马攻击
    int kn[8][2] = {{-2,-1}, {-2,1}, {-1,-2}, {-1,2},
                    {1,-2}, {1,2}, {2,-1}, {2,1}};
    for(int i = 0; i < 8; i++){
        int r = kr + kn[i][0], c = kc + kn[i][1];
        if(r >= 0 && r < 8 && c >= 0 && c < 8){
            char p = b[r][c];
            if(iw && p=='n') return true;
            if(!iw && p=='N') return true;
        }
    }
    // 判断国王此时是否受皇后或车攻击
    int ro[4][2] = {{-1,0}, {1,0}, {0,-1}, {0,1}};
    for(int i = 0; i < 4; i++){
        int r = kr, c = kc;
        while(1){
            r += ro[i][0], c += ro[i][1];
            if(r < 0 || r >= 8 || c < 0 || c >= 8) break;
            char p = b[r][c];
            if(p != '.'){
                if(iw && (p=='r' || p=='q')) return true;
                if(!iw && (p=='R' || p=='Q')) return true;
                break;
            }
        }
    }
    // 判断国王此时是否受皇后或象攻击
    int bi[4][2] = {{-1,-1}, {-1,1}, {1,-1}, {1,1}};
    for(int i = 0; i < 4; i++){
        int r = kr, c = kc;
        while(1){
            r += bi[i][0], c += bi[i][1];
            if(r < 0 || r >= 8 || c < 0 || c >= 8) break;
            char p = b[r][c];
            if(p != '.'){
                if(iw && (p=='b' || p=='q')) return true;
                if(!iw && (p=='B' || p=='Q')) return true;
                break;
            }
        }
    }
    // 判断国王此时是否受另一方国王攻击
    int ki[8][2] = {{-1,-1}, {-1,0}, {-1,1}, {0,-1},
                    {0,1}, {1,-1}, {1,0}, {1,1}};
    for(int i = 0; i < 8; i++){
        int r = kr + ki[i][0], c = kc + ki[i][1];
        if(r >= 0 && r < 8 && c >= 0 && c < 8){
            char p = b[r][c];
            if(iw && p=='k') return true;
            if(!iw && p=='K') return true;
        }
    }
    return false;
}
string pr(const string &s){ // 解析 FEN 格式的棋局
    string r = "";
    for(int i = 0; i < s.size(); i++){
        char ch = s[i];
        if(isdigit(ch)){
            int cnt = ch - '0';
            r.append(cnt, '.');
        }
        else r.push_back(ch);
    }
    return r;
}
int main(){
    int t;
    cin >> t;
    while(t--){
        string fen;
        cin >> fen;
        vector<string> p;
        string tk = "";
        for(int i = 0; i < fen.size(); i++){
            char ch = fen[i];
            if(ch=='/'){
                p.push_back(tk);
                tk = "";
            }
            else tk.push_back(ch);
        }
        p.push_back(tk);
        vector<string> b(8);
        for(int i = 0; i < 8; i++){
            b[i] = pr(p[i]);
            if(b[i].size() < 8)
                b[i].append(8 - b[i].size(), '.');
        }
        int wr = -1, wc = -1, br = -1, bc = -1;
        for(int i = 0; i < 8; i++){
            for(int j = 0; j < 8; j++){
                if(b[i][j]=='K'){
                    wr = i;
                    wc = j;
                }
                if(b[i][j]=='k'){
                    br = i;
                    bc = j;
                }
            }
        }
        if(wr != -1 && at(wr, wc, true, b))
            cout << "check" << "\n";
        else if(br != -1 && at(br, bc, false, b))
            cout << "CHECK" << "\n";
        else
            cout << "none" << "\n";
    }

    return 0;
}

AC 记录

珍惜生命,远离抄袭!