[codeforces 1311E] Construct the Binary Tree  一条路走到底 完全二叉树+链

Codeforces Round #624 (Div. 3)   比赛人数6075

[codeforces 1311E] Construct the Binary Tree  一条路走到底   完全二叉树+链

总目录详见https://blog.csdn.net/mrcrack/article/details/103564004

在线测评地址https://codeforces.ml/contest/1311/problem/E

ProblemLangVerdictTimeMemory
E - Construct the Binary Tree GNU C++11Accepted31 ms0 KB

手模了一下,发现深度和的最大值是链,深度和的最小值是完全二叉树
NO比较容易处理
最大值(n-1+1)*(n-1)/2
最小值2^k-1<=n<=2^(k+1)-1;2^1*1+2^2*2+2^3*3+...+(n-(2^k-1))*k

手工能比较快的画出符合条件的二叉树,不过,编程,感觉比较困难。

n=6,sum=[8,15]演化过程如下图

 根据演化过程,编码如下:

#include <cstdio>
#include <algorithm>
#include <cstring>
#define maxn 5010
using namespace std;
int used[maxn],fa[maxn],dep[maxn],node[maxn];
int main(){
	int t,n,d,i,maxd,now,pre;
	scanf("%d",&t);
	while(t--){
		scanf("%d%d",&n,&d);
		fa[1]=0,maxd=0,dep[1]=0,memset(used,0,sizeof(used));
		for(i=2;i<=n;i++){//构造完全二叉树
			fa[i]=i/2;//fa[i]=j   节点i的父亲是j
			dep[i]=dep[i/2]+1;//dep[i]=j   节点i的深度是j
			d-=dep[i];
			maxd=max(maxd,dep[i]);//最大深度
		}
		if(d<0){//完全二叉树对应着和值最小
			printf("NO\n");
			continue;
		}
		now=n;
		while(now){//找到最深链
			node[dep[now]]=now;//node[i]=j 链上深度为i对应节点j
			used[now]=1;//used[i]=1 节点i已经在链上了
			now=fa[now];
		}
		for(i=n;i>=1;i--){//完全二叉树逐渐向链转变
			if(used[i])continue;
			pre=maxd;
			while(dep[i]<=pre&&d){//dep[i]<=pre没有增加链的长度,d>0还有和值
				fa[i]=node[dep[fa[i]]+1];
				dep[i]+=1;
				if(dep[i]>maxd)maxd=dep[i],node[maxd]=i;//节点i已经将链增长了1
				d--;
			}
		}
		if(d>0){//链是最长,若还有剩,则不现实
			printf("NO\n");
			continue;
		}
		printf("YES\n");
		for(i=2;i<=n;i++)printf("%d ",fa[i]);
		printf("\n");
	}
	return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值