1 条题解
-
0
算法思路
解析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
- 上传者