1 条题解
-
0
题意分析
在 $n\times m$ 大小的棋盘上,已知若干皇后、骑士和兵的位置。统计空格中,不在任何骑士跳跃攻击路径上且不在任何皇后直线可见攻击路径上的格子数(兵阻挡皇后视线)。
解题思路
- 初始化棋盘:用二维数组
grid
大小 $(n+1)\times(m+1)$,标记:0=空,1=皇后,2=骑士,3=兵,4=受攻击。 - 骑士攻击:对每个骑士位置 $(r,c)$,枚举 8 种跳跃偏移,将落在 $1\le r'\le n,1\le c'\le m$ 且当前
grid[r'][c']==0
的格子标记为 4。 - 皇后攻击:对每个皇后位置 $(r,c)$,沿 8 个方向步进,在遇到兵或骑士(
grid==2
或==3
)时停止,否则若grid==0
则标记为 4。 - 统计安全格:遍历所有 $1\le i\le n,1\le j\le m$,计数
grid[i][j]==0
的格子数。
本题代码
#include <iostream> #include <cstdio> using namespace std; int n, m; int grid[1005][1005]; int kx[8] = {-2,-2,-1,-1,1,1,2,2}; int ky[8] = {1,-1,2,-2,2,-2,1,-1}; bool inBoard(int r, int c) { return r >= 1 && r <= n && c >= 1 && c <= m; } int main() { int boardId = 0; while (true) { cin >> n >> m; if (n == 0 && m == 0) break; // 清空标记 for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) grid[i][j] = 0; // 读入皇后 int q; cin >> q; for (int i = 0; i < q; ++i) { int r, c; cin >> r >> c; grid[r][c] = 1; } // 读入骑士 int kn; cin >> kn; for (int i = 0; i < kn; ++i) { int r, c; cin >> r >> c; grid[r][c] = 2; } // 读入兵 int p; cin >> p; for (int i = 0; i < p; ++i) { int r, c; cin >> r >> c; grid[r][c] = 3; } // 骑士攻击 for (int i = 1; i <= n; ++i) { for (int j = 1; j <= m; ++j) { if (grid[i][j] == 2) { for (int d = 0; d < 8; ++d) { int ni = i + kx[d]; int nj = j + ky[d]; if (inBoard(ni, nj) && grid[ni][nj] == 0) { grid[ni][nj] = 4; } } } } } // 皇后攻击 int dx[8] = {-1,1,0,0,-1,-1,1,1}; int dy[8] = {0,0,-1,1,-1,1,-1,1}; for (int i = 1; i <= n; ++i) { for (int j = 1; j <= m; ++j) { if (grid[i][j] == 1) { for (int dir = 0; dir < 8; ++dir) { int ni = i, nj = j; while (true) { ni += dx[dir]; nj += dy[dir]; if (!inBoard(ni, nj)) break; if (grid[ni][nj] == 2 || grid[ni][nj] == 3) break; if (grid[ni][nj] == 0) grid[ni][nj] = 4; } } } } } // 统计安全格 int safeCount = 0; for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) if (grid[i][j] == 0) ++safeCount; printf("Board %d has %d safe squares.\n", ++boardId, safeCount); } return 0; }
- 初始化棋盘:用二维数组
- 1
信息
- ID
- 1734
- 时间
- 1000ms
- 内存
- 64MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者