HDU 5573 Binary Tree(2015-ICPC-上海赛区)

题目连接:题目

大意:

有一颗完全二叉树,第一个节点是1,他的左儿子就是i x 2,右儿子是i x 2+1

然后让你找到一个路径,使得通过加减恰好向下走k步之后,权值和为n,

解题思路:

构造题

首先我们可以分析得到,所有答案都可以通过走 1,2,4,8,16.....来得到

为什么?因为n<=2^k.

如果是奇数,那么我们最后一步就选左儿子,否则选择右儿子

路径问题解决了,我们就差符号问题了

符号问题,我们就可以通过找规律来解决

比如 n的二进制为100101

那么我们k步的符号就可以是110010(1表示+,0表示-)

就第一个位置是1,其他位置都是0就好了

比如001,你可以通过4-2-1来构造出来,就是001->100

--------------------

构造题好费脑

#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
using namespace std;
long long n,k;
int flag=0;
int a[100+10];

int main(int argc, char const *argv[])
{
	int t;scanf("%d",&t);
	for(int p=1;p<=t;p++){
		scanf("%lld%lld",&n,&k);
		flag=0;
		memset(a,0,sizeof(a));
		if(n%2==0){		//构造奇数
			flag=1;
			n=n-1;
		}
		int tmp=0;
		for(int i=k-1;i>=0;i--){
			a[i]=1-tmp;
			tmp=1;
			if((n>>i)&1)
			{
				tmp=0;
				printf("%d %d\n",(n>>i)&1,i);
			} 
			
		}
		printf("Case #%d:\n",p);
		long long now = 1;
		for(int i=0;i<k-1;i++){
			printf("%lld ",now);
			now = now*2;
			if(a[i]) printf("+\n");
			else printf("-\n");
		}
		if(flag) printf("%lld ",now+1);
		else printf("%lld ",now);
		if(a[k-1]) printf("+\n");
		else printf("-\n");

	}
	return 0;
}



posted @ 2016-10-17 12:18  hong-ll  阅读(181)  评论(0编辑  收藏  举报