http://boj.me/onlinejudge/newoj/showProblem/show_problem.php?problem_id=212
这是区域赛北京赛区的一个题,题意不难,就是树的遍历过程。输入是一个长字符串,同一对括号中的字符串属于同一等级的结点,第一个是根结点,比如a(b,c(d,e),f)这个输入,表示根结点为a,a有三个子结点b,c,f,其中c有两个子结点d,e,要求根据输入的字符串得到以下信息:1、总结点数。2、各结点名(用字符串表示)。3、遍历过程(用数字序号表示各结点)。比如上面的输入得到的输出就是:
6
a
b
c
d
e
f
1 2
2 1
1 3
3 4
4 3
3 5
5 3
3 1
1 6
6 1
注意,不仅要输出从双亲结点到子结点的路径,也要输出从子结点返回双亲结点的路径。此题用栈结构很简单,时间方面还是很理想的。
#include<iostream> #include<stack> using namespace std; char str[1000005]; stack<int> s; int main() { int i, ncase; int top, cnt, len, k; bool flag; scanf("%d", &ncase); while (ncase--) { scanf("%s", str); len = strlen(str); while (!s.empty()) s.pop(); cnt = 0; flag = false; for (i=0; i<len; i++) { if (str[i]!='(' && str[i]!=')' && str[i]!=',') { flag = true; } else { if (flag==true) cnt++; flag = false; } } if (cnt==0) printf("1\n"); else printf("%d\n", cnt); flag = false; for (i=0; i<len; i++) { if (str[i]>='a' && str[i]<='z') flag = true, printf("%c", str[i]); else if (flag) flag = false, printf("\n"); } if (str[len-1]>='a' && str[len-1]<='z') printf("\n"); k = 1; flag = false; for (i=0; i<len; i++) { if (str[i]=='(') { if (!s.empty()) printf("%d %d\n", s.top(), k); s.push(k); k++; } else if (str[i]==',') { if (flag) { printf("%d %d\n", s.top(), k); printf("%d %d\n", k, s.top()); k++; flag = false; } else { top = s.top(); s.pop(); printf("%d %d\n", top, s.top()); } } else if (str[i]==')') { if (flag) { printf("%d %d\n", s.top(), k); printf("%d %d\n", k, s.top()); k++; flag = false; } else { top = s.top(); s.pop(); printf("%d %d\n", top, s.top()); } } else flag = true; } printf("\n"); } return 0; }