HDU 5573 Binary Tree(构造题)

http://acm.hdu.edu.cn/showproblem.php?pid=5573

题意:
给出一个满二叉树,根节点权值为1,左儿子为2*val,右儿子为2*val+1。现在有只青蛙从根节点出发,一步步往下走,在每个节点它都要选择加上该点的权值还是减去该点的权值,如果正好经过k个节点时总的权值和为n,那么这只青蛙就成功了,需要输出方案。

思路:

这道题目要注意到n<=(1<<k)。

所以如果每次都走这棵二叉树的左节点的话,权值就是1,2,4,8,10,那么它就可以组成小于(1<<k)的所有偶数,如果组成所有奇数的话,只要最后一步走右节点即可。

现在设走左节点的权值和是sum,那么多余的部分就是sum-n,那么我们只需要把(sum-n)/2这部分变成负数就可以,那么这里就又存在一个问题了,就是sum-n有可能是奇数,如果是这种情况的话就让最后一步走右节点,这样的话sum-n就又变成偶数了。

那么怎么去凑(sum-n)/2呢,很简单,还是根据二进制,相应位的节点改为负即可。

 #include<iostream>
#include<cstdio>
using namespace std;
const int maxn = +;
typedef long long ll; int n, k;
int a[maxn]; int main()
{
//freopen("in.txt","r",stdin);
int T;
int kase = ;
scanf("%d",&T);
while(T--)
{
bool flag = false;
scanf("%d%d",&n,&k);
ll sum = (<<k)-;
ll rest = sum - n;
if(rest&) {flag = true; rest++;}
rest/=;
for(int i=;i<k;i++)
{
if(rest&((ll)<<i)) a[i]=;
else a[i]=;
}
printf("Case #%d:\n",++kase);
for(int i=;i<k;i++)
{
if(i!=k-) printf("%lld ",(ll)<<i);
else if(flag) printf("%lld ",(ll)(<<i)+);
else printf("%lld ",(ll)<<i);
if(a[i]) puts("+");
else puts("-");
}
}
return ;
}
上一篇:Simple Sort


下一篇:LeetCode算法题-Longest Word in Dictionary(Java实现)