列表

详情


NC16660. [NOIP2004]FBI树

描述

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

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

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

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

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

[1] 二叉树:二叉树是结点的有限集合,这个集合或为空集,或由一个根结点和两棵不相交的二叉树组成。这两棵不相交的二叉树分别称为这个根结点的左子树和右子树。

[2] 后序遍历:后序遍历是深度优先遍历二叉树的一种方法,它的递归定义是:先后序遍历左子树,再后序遍历右子树,最后访问根。

输入描述

第一行是一个整数N(0 <= N <= 10)
第二行是一个长度为2N的“01”串。

输出描述

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

示例1

输入:

3
10001011

输出:

IBFBBBFIBFIIIFF

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 3ms, 内存消耗: 396K, 提交时间: 2023-02-19 18:51:09

#include<bits/stdc++.h>
using namespace std;
string a;
char bfs(int l,int r){
	char c,c1,c2;
	if(l==r){
	a[l]=='1'?c='I':c='B';
	cout<<c;}
	else{
		int mid=(l+r)>>1;
		c1=bfs(l,mid);
		c2=bfs(mid+1,r);
		if(c1=='F'||c2=='F'||c1!=c2)
		c='F';
		else
		c=c1;
		cout<<c;
	}
	return c;
}
int main(){
	int n;
	cin>>n;
	cin>>a;
	bfs(0,(1<<n)-1);
	return 0;
}

Pascal(fpc 3.0.2) 解法, 执行用时: 2ms, 内存消耗: 376K, 提交时间: 2019-09-08 07:27:49

var
a,s:string;
i,n:longint;

function aa(i:longint):char;
var
l,r:char;
begin
if (1<<n)<=i then begin write(s[i-1<<n+1]); exit(s[i-1<<n+1]); end;
l:=aa(2*i);
r:=aa(2*i+1);
if l=r then begin write(l); exit(l); end;
write('F'); exit('F');
end;

begin
readln(n);
readln(a);
for i:=1 to 1<<n do
 if a[i]='1' then s:=s+'I' else s:=s+'B';
s:=s+aa(1);
end.

C++14(g++5.4) 解法, 执行用时: 3ms, 内存消耗: 596K, 提交时间: 2019-09-10 21:11:17

#include<bits/stdc++.h>
using namespace std;
int n;string s;
void dfs(int l,int r)
{
	int mid=(l+r)/2;
	if(l!=r)
	{
		dfs(l,mid);dfs(mid+1,r);
	}
	int x,y;x=y=0;
	for(int i=l;i<=r;i++)
	{
		if(s[i]=='0')	x++;else y++;
	}
    if(x&&y)	cout<<"F";if(x&&(!y))	cout<<"B";if((!x)&&y)	cout<<"I";
}
int main()
{
	cin>>n>>s;
	dfs(0,s.size()-1);
}

Python(2.7.3) 解法, 执行用时: 14ms, 内存消耗: 2828K, 提交时间: 2021-03-11 17:01:21

def fbi(s):
    l = len(s)
    if l == 1:
        return 'B' if s[0] == '0' else 'I'
    left_tree = fbi(s[0: l / 2])
    right_tree = fbi(s[l / 2:])
    root = 'F'
    if left_tree == right_tree:
        root = left_tree[-1]
    return left_tree + right_tree + root
  
n = raw_input()
n = int(n)
s = raw_input()
print fbi(s)

C++(clang++ 11.0.1) 解法, 执行用时: 2ms, 内存消耗: 404K, 提交时间: 2022-08-18 08:22:54

#include<bits/stdc++.h>
using namespace std;
void fun(string s)
{
	if(s.size()>1)
	{
		fun(s.substr(0,s.size()/2));
		fun(s.substr(s.size()/2,s.size()/2));
	}
	if(s==string(s.size(),'1'))cout<<"I";
	else if(s==string(s.size(),'0'))cout<<"B";
	else cout<<"F";
}
int main(){
	int n;
	string s;
	cin>>n>>s;
	fun(s);
	return 0;
}

上一题