程序设计天梯赛2021年选拔 L2-4红豆 (什么完全树给定后序遍历)

这篇博客讨论了一种处理完全二叉树后序遍历的方法,通过建立树结构并进行查询。在给定不超过60个节点的完全二叉树中,根据后序遍历构建树,并对m组查询进行处理。对于每个查询点x,如果存在于树中则标记该子树并输出标记的叶子数量;如果已被标记则输出特定信息。最后输出所有未被标记的节点的前序遍历。代码实现包括建树、查询和前序遍历等功能。
摘要由CSDN通过智能技术生成

题目
题意: 给定一棵n个节点的完全二叉树的后序遍历(不一定满足是2^k-1,但是只会在右边缺点。n<=60)。给定m组查询,对于给定点x。判断是否在书中。若在树中,则将以它为根的子树全部标记上,并输出本次操作中标记的叶子的数量。若已经被标记,则输出一句奇奇怪怪的话。最后输出所有未被标记的点形成的前序遍历。
思路: 根据完全二叉树的特点建树即可,开个数组。递归的建树,先儿子,再根节点。
时间复杂度: O(m*logn + n) 根据给定的值拿map映射到在树中的下标,反正n很小,无所胃。
代码:

#include<bits/stdc++.h>
using namespace std;
#define mem(a,x) memset(a,x,sizeof(a))
#define fir(i,a,b) for(int i=a;i<=b;++i)
const int N = 1e5+10;
typedef long long ll;
typedef pair<int,int> PII;
int n,m,k,T;
int a[102];
int idx = 0;
int b[102];
bool vis[102];
map<int,int> mp;
void get(int now)
{
	if(now > n)
	{
		return ;
	}
	get(now<<1|1);
	get(now<<1);
	//右、左、根
	a[now] = b[idx++];
}
bool kong = true;
void pre(int now)
{
	if(now > n || vis[now]) return;	
	if(kong)
	printf("%d",a[now]),kong = false;
	else printf(" %d",a[now]);
	pre(now<<1);
	pre(now<<1|1);
}
int mx;
int va[] = {1,3,7,15,31,63};
int dfs(int cur)
{
	// cout<<cur<<"?"<<endl;
	if(cur > n || vis[cur]) return 0;
	vis[cur] = 1;
	if(cur*2>mx) return 1;
	return dfs(cur<<1)+dfs(cur<<1|1);
}
void solve()
{
	cin>>n;
	for(int i=0;;++i)
	{
		if(va[i] >= n)
		{
			mx = va[i];
			break;
		}
	}
	for(int i=0;i<n;++i)
	{
		cin>>b[i];
	}
	get(1);
	for(int i=1;i<=n;++i) mp[a[i]] = i; //x在树中的下标位置
	cin>>m;
	while(m--)
	{
		int root; cin>>root;
		root = mp[root];
		if(root==0)
		{
			cout<<"Kan Qing Chu Le?\n";
		}
		else 
		{
			if(vis[root])
			{
				cout<<"Zao Jiu Cai Diao Le!\n";
			}
			else
			{
				cout<<dfs(root)<<"\n";
			}
		}
	}
	int cnt = 0;
	for(int i=1;i<=n;++i) if(vis[i]) cnt++;
	if(cnt == n)
	{
		cout<<"Kong Le!";
	}
	else
	{
		pre(1);
	}
}
signed main(void)
{
	solve();
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值