題意:給定 R 行 C 列的網格,'.' 表示黑色方塊,'@' 表示起始位置,'#' 表示紅色障礙。從 '@' 出發,只能上下左右移動到 '.' 格子。求可到達的黑色方塊總數(含起點)。多測試用例,R,C ≤ 20。
利用遞歸搜索,訪問過的格子標記為 '*'(或任意非 '.' 字符),避免重複訪問,無需回溯恢復現場。
#include <cstdio>
#include <vector>
#include <string>
using namespace std;
int R, C, cnt;
vector<string> grid;
bool inside(int r, int c) {
return r >= 0 && c >= 0 && r < R && c < C && grid[r][c] == '.';
}
void dfs(int r, int c) {
++cnt;
grid[r][c] = '*';
if (inside(r-1, c)) dfs(r-1, c);
if (inside(r+1, c)) dfs(r+1, c);
if (inside(r, c-1)) dfs(r, c-1);
if (inside(r, c+1)) dfs(r, c+1);
}
int main() {
string line;
while (cin >> C >> R && C) {
grid.clear();
for (int i = 0; i < R; ++i) {
cin >> line;
grid.push_back(line);
}
cnt = 0;
for (int i = 0; i < R; ++i)
for (int j = 0; j < C; ++j)
if (grid[i][j] == '@') {
dfs(i, j);
goto output;
}
output:
printf("%d\n", cnt);
}
return 0;
}
grid[r][c] 為 '*',省去額外 visited 數組。goto 跳出雙層循環(或用標誌變量)。時間 O(R·C),空間 O(R·C)(存網格)+ O(R·C) 遞歸棧。