1 条题解

  • 0
    @ 2025-5-14 21:38:09

    算法思路

    解析FEN字符串:将FEN字符串转换为一个8x8的棋盘表示。

    标记被攻击的方格:对于棋盘上的每一个棋子,根据其类型和位置,标记所有它能攻击的方格。

    统计安全空格:统计那些既没有被任何棋子占据,也没有被任何棋子攻击的方格数量。

    算法代码

    #include <iostream>
    #include <vector>
    #include <string>
    #include <cctype>
    
    using namespace std;
    
    const int BOARD_SIZE = 8;
    
    // 检查坐标是否在棋盘内
    bool isOnBoard(int x, int y) {
        return x >= 0 && x < BOARD_SIZE && y >= 0 && y < BOARD_SIZE;
    }
    
    // 标记被攻击的格子
    void markAttacked(vector<vector<bool>>& attacked, int x, int y, int dx, int dy, const vector<vector<char>>& board) {
        x += dx;
        y += dy;
        while (isOnBoard(x, y)) {
            attacked[x][y] = true;
            if (board[x][y] != ' ') break;
            x += dx;
            y += dy;
        }
    }
    
    // 处理每个棋子的攻击范围
    void processPiece(vector<vector<bool>>& attacked, int x, int y, char piece, const vector<vector<char>>& board) {
        switch (tolower(piece)) {
            case 'p': {
                int dir = isupper(piece) ? -1 : 1;
                if (isOnBoard(x + dir, y - 1)) attacked[x + dir][y - 1] = true;
                if (isOnBoard(x + dir, y + 1)) attacked[x + dir][y + 1] = true;
                break;
            }
            case 'n': {
                int knightMoves[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 newX = x + knightMoves[i][0];
                    int newY = y + knightMoves[i][1];
                    if (isOnBoard(newX, newY)) attacked[newX][newY] = true;
                }
                break;
            }
            case 'b': {
                markAttacked(attacked, x, y, -1, -1, board);
                markAttacked(attacked, x, y, -1, 1, board);
                markAttacked(attacked, x, y, 1, -1, board);
                markAttacked(attacked, x, y, 1, 1, board);
                break;
            }
            case 'r': {
                markAttacked(attacked, x, y, -1, 0, board);
                markAttacked(attacked, x, y, 1, 0, board);
                markAttacked(attacked, x, y, 0, -1, board);
                markAttacked(attacked, x, y, 0, 1, board);
                break;
            }
            case 'q': {
                markAttacked(attacked, x, y, -1, -1, board);
                markAttacked(attacked, x, y, -1, 1, board);
                markAttacked(attacked, x, y, 1, -1, board);
                markAttacked(attacked, x, y, 1, 1, board);
                markAttacked(attacked, x, y, -1, 0, board);
                markAttacked(attacked, x, y, 1, 0, board);
                markAttacked(attacked, x, y, 0, -1, board);
                markAttacked(attacked, x, y, 0, 1, board);
                break;
            }
            case 'k': {
                int kingMoves[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 newX = x + kingMoves[i][0];
                    int newY = y + kingMoves[i][1];
                    if (isOnBoard(newX, newY)) attacked[newX][newY] = true;
                }
                break;
            }
        }
    }
    
    // 根据 FEN 字符串构建棋盘
    vector<vector<char>> buildBoard(const string& fen) {
        vector<vector<char>> board(BOARD_SIZE, vector<char>(BOARD_SIZE, ' '));
        int x = 0, y = 0;
        for (char c : fen) {
            if (c == '/') {
                x++;
                y = 0;
            } else if (isdigit(c)) {
                y += c - '0';
            } else {
                board[x][y] = c;
                y++;
            }
        }
        return board;
    }
    
    // 计算未被攻击的空格数
    int countUnattacked(const vector<vector<char>>& board) {
        vector<vector<bool>> attacked(BOARD_SIZE, vector<bool>(BOARD_SIZE, false));
        for (int i = 0; i < BOARD_SIZE; ++i) {
            for (int j = 0; j < BOARD_SIZE; ++j) {
                if (board[i][j] != ' ') {
                    processPiece(attacked, i, j, board[i][j], board);
                }
            }
        }
        int count = 0;
        for (int i = 0; i < BOARD_SIZE; ++i) {
            for (int j = 0; j < BOARD_SIZE; ++j) {
                if (board[i][j] == ' ' && !attacked[i][j]) {
                    count++;
                }
            }
        }
        return count;
    }
    
    int main() {
        string fen;
        while (cin >> fen) {
            vector<vector<char>> board = buildBoard(fen);
            int result = countUnattacked(board);
            cout << result << endl;
        }
        return 0;
    }    
    
    
    • 1

    信息

    ID
    1513
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    4
    已通过
    1
    上传者