CF-div3-624-E. Construct the Binary Tree

debug一中午,补题时间不可控啊

思路

1.先当作一整条链来做,这样深度最深,记作cnt
2.再从底向上,一个点一个点选择位置,选择什么样的位置?从上到下数要是这一层有空位就放进去,也就是构造成满二叉树的形状
每次选位置的时候算一下距离cnt-deep能不能凑成d

代码

没去CF交,不知道有没有ac,不管了,万一交了又..模拟写的太烦了,一中午没了要念首诗冷静下
AC了AC了!

#include<bits/stdc++.h>
using namespace std;

const int maxn = 5100;
int t; 
int n,d,cnt = 0;
int depth[maxn];
int deepNum[maxn],finalNum[maxn];
int fa[maxn];
int nodeNum,height;

void init(){
	cnt = 0;
	for(int i=0;i<=n;i++){
		finalNum[i] = 0,deepNum[i] = 0;
	}
	for(int i=0;i<=n-1;i++) 
		depth[i] = i,cnt+=i,deepNum[i]++,fa[i]=0;
	nodeNum = n-1,height = 1;
}

int getDeep(){
	if(deepNum[height] < pow(2,height)){
//		cout<<nodeNum<<" "<<height<<" "<<deepNum[height]<<" "<<pow(2,height)<<endl;
		deepNum[height]++;
	}else{
		height++;
		deepNum[height]++;
	}
	return height;
}

void print(){
	for(int i=1;i<=n-1;i++) printf("%d%c",depth[i],i==n?'\n':' '); 
}

int main(){
	cin>>t;
	while(t--){
		cin>>n>>d;
		init();
		if(cnt < d){
			puts("NO");
			continue;
		}
		while(cnt > d){
			int height = getDeep();
			if(height>=nodeNum) break;
			int value1 = nodeNum - height;
			int value2 = cnt - d; 
			if(value1 <= value2){
				depth[nodeNum] = height;
				cnt -= value1;
			}else{
				depth[nodeNum] -= value2;
				cnt = d;
			} 
			nodeNum--;
		}
//		print();
		if(cnt != d){
			puts("NO");
			continue;
		}
		puts("YES");
		for(int i=1;i<=n-1;i++){
			for(int j=0;j<=n-1;j++){
				if(depth[j] == depth[i] - 1 && finalNum[j] < 2){
					fa[i] = j;
					finalNum[j]++;
					break;
				}
			}
		}
		for(int i=1;i<=n-1;i++){
			printf("%d%c",fa[i]+1,i==n-1 ? '\n':' ');
		}
	}
	return 0;
}

/*
3
5 7
10 19
10 18

1
5 7 

1
10 19
*/
posted @ 2020-02-26 14:21  fishers  阅读(96)  评论(0编辑  收藏  举报