P1087 FBI树(洛谷题解最佳独创版---栈运算)

空降题目:

题目描述

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

FBI 树是一种二叉树,它的结点类型也包括 F 结点,B 结点和 I 结点三种。由一个长度为 2^N2N 的 01 串 SS 可以构造出一棵 FBI 树 TT,递归的构造方法如下:

  1. TT 的根结点为 RR,其类型与串 SS 的类型相同;
  2. 若串 SS 的长度大于 11,将串 SS 从中间分开,分为等长的左右子串 S_1S1​ 和 S_2S2​;由左子串 S_1S1​ 构造 RR 的左子树 T_1T1​,由右子串 S_2S2​ 构造 RR 的右子树 T_2T2​。

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

输入格式

第一行是一个整数 N(0 \le N \le 10)N(0≤N≤10),

第二行是一个长度为 2^N2N 的 01 串。

输出格式

一个字符串,即 FBI 树的后序遍历序列。

输入输出样例

输入 #1复制

3
10001011

输出 #1复制

IBFBBBFIBFIIIFF

说明/提示

对于 40\%40% 的数据,N \le 2N≤2;

对于全部的数据,N \le 10N≤10。

noip2004普及组第3题

思路:

我们首先应该知道后序遍历的特点:左右根

所以要用到一个栈

什么是栈不会还有人不知道吧

详见浅谈STL函数库_火龙果殿下的博客-CSDN博客

stack<int> q;

然后用递归反复操作;

有三种情况:

1.长度为1:

    1)是B串

    2)是I串

2.长度不为1:

    1)是B串

    2)是I串

3.是F串

先入栈:

string a;//初始输入字符串
if(a.size()==1){
		if(a=="1") q.push('I');
		else q.push('B');
		return;
	}
	bool flag=true;
	for(int i=0;i<a.size();i++){
		if(a[i]=='1')flag=false;
	}
	if(flag){
		q.push('B');
	}
	else{
		flag=true;
	    for(int i=0;i<a.size();i++){
		    if(a[i]=='0')flag=false;
    	}
    	if(flag){
    		q.push('I');
    	}
    	else{
    		q.push('F');
		}
	}

然后将字符串分为左右两部分,进行递归

注意,由于是栈,所以要先搜索右子树,再搜索左子树

string b,c;
	for(int i=0;i<a.size()/2;i++){
		b+=a[i];
	}
	for(int i=a.size()/2;i<a.size();i++){
		c+=a[i];
	}
	postorder(c);
	postorder(b);

最后输出

void print(){
	while(!q.empty()){
		cout<<q.top();
		q.pop();
	}
}

完整代码

#include<bits/stdc++.h>
#include<stack>
using namespace std;
stack<char> q;
void print(){
	while(!q.empty()){
		cout<<q.top();
		q.pop();
	}
}
void postorder(string a){
	if(a.size()==1){
		if(a=="1") q.push('I');
		else q.push('B');
		return;
	}
	bool flag=true;
	for(int i=0;i<a.size();i++){
		if(a[i]=='1')flag=false;
	}
	if(flag){
		q.push('B');
	}
	else{
		flag=true;
	    for(int i=0;i<a.size();i++){
		    if(a[i]=='0')flag=false;
    	}
    	if(flag){
    		q.push('I');
    	}
    	else{
    		q.push('F');
		}
	}
	string b,c;
	for(int i=0;i<a.size()/2;i++){
		b+=a[i];
	}
	for(int i=a.size()/2;i<a.size();i++){
		c+=a[i];
	}
	postorder(c);
	postorder(b);
}
int main(){
	int n;
	string a;
	cin>>n>>a;
	postorder(a);
	print();
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值