BOJ212 树的先序遍历

 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;
}

你可能感兴趣的:(c)