(Luogu) P1087 FBI树 P1030 求先序排列

https://www.luogu.org/problemnew/show/P1087

#include<bits/stdc++.h>
using namespace std;
string s[4000],ff;
int N;
void pd(string xx){
	bool flag0=0,flag1=0;
	for(int i=0;i<xx.size();++i){
		if(flag0 && flag1)	break;
		if(xx[i]=='1')	flag1=1;
		else flag0=1;
	}
	if(flag0&&flag1)	cout<<'F';
	else if(flag1)	cout<<'I';
	else	cout<<'B';
}
void CreatTree(string tt,int dep){
	if(tt.size()==1){
		s[dep]=tt;
		return;
	}
	else{
		s[dep]=tt;
		string le=tt.substr(0,tt.size()/2);
		string ri=tt.substr(tt.size()/2,tt.size()/2);
		CreatTree(le,dep<<1);
		CreatTree(ri,dep<<1|1);
	}
}
void postOrde(int dep) {
	if(s[dep].size()==1){
		pd(s[dep]);
		return ;
	}
	else {
		postOrde(dep<<1);
		postOrde(dep<<1|1);
		pd(s[dep]);
	}
}
int main(){
	cin>>N>>ff;
	if(ff.size()==1)	pd(ff);
	else{
		CreatTree(ff,1);
		postOrde(1);
	}
	return 0;
}

树的建立和三种遍历https://blog.csdn.net/TDD_Master/article/details/83186422

 

更新下划线——————————————————————————————

https://www.luogu.org/problemnew/show/P1030#sub

后序遍历时 根节点总是在最后被访问到。

那中序遍历 根节点的左右两侧的点恰是它的左右子树。

所以利用这一点就可以求出前序遍历 那例子举个栗子

中序: BADC
后序: BDCA

根据后序第一个输出的肯定是A,然后看中序,A的左边是B(即左枝),右边是DC(即右枝)

先递归左枝,左枝的中序遍历是B,后序遍历也是B,输出B。递归右枝,中序遍历是DC,后序遍历是DC

先输出根C,递归左枝(输出D),右枝无。一层层下去,前序遍历就输出出来了。

 

#include<bits/stdc++.h>
#include<string>
using namespace std;
string mmm,pos;
void dfs(string m,string p){
	if(p.size()==1){
		cout<<p;
		return ;
	}
	cout<<p[p.size()-1];
	int i;
	for(i=0;i<m.size();++i){
		if(m[i]==p[p.size()-1]){
			break;
		}
	}
	if(i>0){//有左枝 
		string lm=m.substr(0,i),lp=p.substr(0,i);
		dfs(lm,lp);
	}
	if(i<m.size()-1){//有右枝 
		string rm=m.substr(i+1),rp=p.substr(i,p.size()-i-1);
		dfs(rm,rp);
	}
}
int main(){
	cin>>mmm>>pos;
	dfs(mmm,pos);
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值