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

文章描述了一种名为FBI树的数据结构,它是基于01字符串构建的二叉树。在给定特定长度的01串时,通过递归方法构造FBI树并输出其后序遍历序列。主要涉及后序遍历的特性、栈的使用以及如何根据字符串内容判断节点类型(B结点、I结点或F结点)。

空降题目:

题目描述

我们可以把由 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函数库_火龙果殿下的博客-优快云博客

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

### 洛谷 P9496 「RiOI-2」hacker 题解与代码实现 在洛谷 P9496 「RiOI-2」hacker 的题目中,问题的核心在于处理字符串的匹配与判断。根据已知的引用内容[^1],可以推断出该题可能涉及对特定字符串模式的查找和验证。 #### 问题分析 此题需要判断给定的两个字符串是否满足某种条件,具体条件为:其中一个字符串或两个字符串都包含子串 "rioi"(不区分大小写)。若两个字符串均符合条件,则输出 "Either is ok!";若仅一个字符串符合条件,则输出对应字符串及 "for sure!";若两者均不符合条件,则输出 "Try again!"。 #### 解题思路 通过将字符串转换为小写形式后进行子串查找,可以有效解决大小写敏感的问题。以下是实现这一逻辑的具体步骤: 1. 定义一个辅助函数 `is_good`,用于判断字符串是否包含子串 "rioi"。 2. 在主函数中读取输入的两个字符串,并调用辅助函数分别检查两者的条件。 3. 根据检查结果输出对应的答案。 #### 代码实现 以下为 C++ 实现代码: ```cpp #include <bits/stdc++.h> using namespace std; bool is_good(string str) { string lower_str = str; transform(lower_str.begin(), lower_str.end(), lower_str.begin(), ::tolower); // 将字符串转换为小写 return lower_str.find("rioi") != string::npos; // 检查小写字符串中是否包含 "rioi" } int main() { string s, t; cin >> s >> t; // 检查两个字符串是否都是好闪的 if (is_good(s) && is_good(t)) { cout << "Either is ok!" << endl; } // 检查第一个字符串是否是好闪的 else if (is_good(s)) { cout << s << " for sure!" << endl; } // 检查第二个字符串是否是好闪的 else if (is_good(t)) { cout << t << " for sure!" << endl; } // 如果两个字符串都不是好闪的 else { cout << "Try again!" << endl; } return 0; } ``` #### 复杂度分析 - **时间复杂度**:O(n + m),其中 n 和 m 分别为两个字符串的长度。字符串转换为小写的时间复杂度为 O(n + m),子串查找的时间复杂度同样为 O(n + m)[^2]。 - **空间复杂度**:O(n + m),主要由辅助字符串 `lower_str` 占用。 ### 注意事项 对于某些评测机可能存在不稳定的情况,建议多次提交以确保结果的准确性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值