1094 FBI树 2004年NOIP全国联赛普及组

题目连接 http://codevs.cn/problem/1094/

题目描述 Description

我们可以把由“0和“1组成的字符串分为三类:全“0串称为B串,全“1串称为I串,既含“0又含“1的串则称为F串。

FBI树是一种二叉树[1],它的结点类型也包括F结点,B结点和I结点三种。由一个长度为2N的“01S可以构造出一棵FBIT,递归的构造方法如下:

1) T的根结点为R,其类型与串S的类型相同;

2) 若串S的长度大于1,将串S从中间分开,分为等长的左右子串S1S2;由左子串S1构造R的左子树T1,由右子串S2构造R的右子树T2

现在给定一个长度为2N的“01串,请用上述构造方法构造出一棵FBI树,并输出它的后序遍历[2]序列。

输入描述 Input Description

输入的第一行是一个整数N0 <= N <= 10),第二行是一个长度为2N的“01串。

输出描述 Output Description

输出t包括一行,这一行只包含一个字符串,即FBI树的后序遍历序列。

样例输入 Sample Input

3

10001011

样例输出 Sample Output

IBFBBBFIBFIIIFF

数据范围及提示 Data Size & Hint

对于40%的数据,N <= 2

对于全部的数据,N <= 10


输入N没用。

后续遍历,得出串的 范围,然后检查类型,输出结果。

#include <iostream>
using namespace std;
enum ZOSTR{ZERO,ONE,ZEROONE};
inline ZOSTR checkType(const string& str,int head,int tail)
{
	bool zero = false;
	bool one = false;
	for (int i = head; i <= tail; i++)
	{
		if (str[i] == '0')
			zero = true;
		else if (str[i] == '1')
			one = true;
		if (zero&&one)
			break;
	}
	if (zero&&one)
		return ZEROONE;
	else if (zero)
		return ZERO;
	else
		return ONE;
}
void optFBItree(const string& str,int head,int tail,bool end)  // end用来检查叶子是否已经遍历完
{
	if (head <= tail && !end)
	{
		if (head == tail && !end)
		{
			end = true;
		}
		optFBItree(str,head,(head+tail)/2,end);
		optFBItree(str,(head+tail)/2+1,tail,end);
		string otput;
		switch(checkType(str,head,tail))
		{
			case ZERO:
				otput = "B";
				break;
			case ONE:
				otput = "I";
				break;
			case ZEROONE:
				otput = "F";
				break;
		}
		cout<<otput;
	}
}

int main(int argc, char** argv) {  // 去掉前导符,然后加上数量
	int N;
	string str;
	cin >> N;
	cin >> str;
	optFBItree(str,0,str.size()-1,false);
	cout<<endl;
}



你可能感兴趣的:(1094 FBI树 2004年NOIP全国联赛普及组)