魔法少女圓香在樹狀迷宮中消滅女巫。迷宮以樹表示,節點為房間,邊為通道。圓香從根節點開始,遵循規則:
輸入為一個括號字串表示樹結構(如 walpurgis(charlotte(patricia,gertrud),elly,gisela)),要求輸出:節點數、消滅順序的女巫名字、圓香移動軌跡(節點編號對)。
此過程本質是樹的先序遍歷(根→左→右),但需記錄「進入」與「退出」每個節點的時刻,形成軌跡。
(、)、, 分隔。父 子,每次回溯到父節點輸出 子 父。棧頂 當前編號(下行),壓入棧。, 或 ) → 彈出棧頂(回溯),若棧非空,輸出 彈出節點 新棧頂(上行)。#include <cstdio>
#include <cstring>
#include <stack>
using namespace std;
char str[1000005], name[105];
char names[50005][105];
int main() {
int T; scanf("%d", &T);
while (T--) {
scanf("%s", str);
int len = strlen(str);
int n = 0, pos = 0;
bool inName = false;
// 提取名字
for (int i = 0; i < len; ++i) {
if (str[i] >= 'a' && str[i] <= 'z') {
name[pos++] = str[i];
inName = true;
} else {
if (inName) {
name[pos] = '\0';
strcpy(names[n++], name);
pos = 0;
inName = false;
}
}
}
if (inName) { name[pos] = '\0'; strcpy(names[n++], name); }
printf("%d\n", n);
for (int i = 0; i < n; ++i) printf("%s\n", names[i]);
stack st;
int cur = 1;
for (int i = 0; i < len; ++i) {
if (str[i] == '(') continue;
if (str[i] >= 'a' && str[i] <= 'z' &&
(i+1 >= len || str[i+1] < 'a' || str[i+1] > 'z')) {
if (!st.empty()) printf("%d %d\n", st.top(), cur);
st.push(cur++);
}
if (str[i] == ',' || str[i] == ')') {
printf("%d ", st.top()); st.pop();
printf("%d\n", st.top());
}
}
putchar('\n');
}
return 0;
}
O(L),L 為字串長度(≤ 1,000,000)。O(N),N 為節點數(≤ 50,000)。