UVA「看圖寫樹」:給定字符矩陣表示的多叉樹(節點為非空格字符,子節點通過 '|' 和 '-' 連接),輸出括號表示法。本文解析 DFS 遞歸解析邏輯:從根節點開始,檢查下方 '|' 和 '-' 尋找子節點。
buf[row][col]。dfs(r, c) 處理位置 (r,c) 的節點:buf[r][c] + "("。buf[r+1][c] == '|' 且 r+1 < 行數:buf[r+2] 向左找到最左邊的 '-',記為 start_col。start_col 向右掃描 '-',對每個位置 col,若 buf[r+3][col] != ' ',遞歸 dfs(r+3, col)。")"。#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 100;
char buf[MAXN][MAXN];
int rows;
void dfs(int r, int c) {
if (r+1 < rows && buf[r+1][c] == '|') {
// 找最左邊的 '-'
int col = c;
while (col-1 >= 0 && buf[r+2][col-1] == '-') col--;
// 掃描所有 '-' 覆蓋的子節點
for (int i = col; i < MAXN && buf[r+2][i] == '-'; ++i) {
if (r+3 < rows && buf[r+3][i] != ' ') {
cout << buf[r+3][i] << "(";
dfs(r+3, i);
}
}
}
cout << ")";
}
int main() {
int T; cin >> T; getchar();
while (T--) {
rows = 0;
memset(buf, 0, sizeof(buf));
while (fgets(buf[rows], MAXN, stdin)) {
buf[rows][strcspn(buf[rows], "\n")] = 0; // 去換行
if (strcmp(buf[rows], "#") == 0) break;
rows++;
}
cout << "(";
if (rows > 0) {
for (int i = 0; i < strlen(buf[0]); ++i) {
if (buf[0][i] != ' ') {
cout << buf[0][i] << "(";
dfs(0, i);
break;
}
}
}
cout << ")" << endl;
}
return 0;
}
fgets 讀整行,去除換行符,遇到 "#" 停止。buf[r][c] 前確保 r < rows。字符(,遞歸處理子女,最後輸出 )。整棵樹外層包一對 ()。輸入: 2 A | ------------- B C D | | ----- E F G # e | ----- f g # 輸出: (A(B()C(E()F())D(G()))) (e(f()g()))
本題是「字符矩陣解析樹結構」的經典問題。關鍵在於理解『| - 子節點』的幾何佈局規則,並用遞歸 DFS 自然映射樹的層次結構。代碼簡潔,核心邏輯集中在 dfs 中的「向左找最左 '-', 向右掃描子節點」兩步。注意邊界條件與輸入讀取細節即可 AC。