BinaryTree(HDU-5573)【思维/构造】

题目链接:https://vjudge.net/problem/HDU-5573

题意:一棵二叉树,编号代表对应节点的取值,可以走k步,每次走的层数递增,问能够达到N的方案。

思路:首先看一下数据范围,N2^K2^60,

  因此,由这颗二叉树从左往右数第一二支即可得到N的最大值。

  当答案的路径在最左侧一支时,设sum=2^k-1,t为要减去的那部分数字的和,则N=sum-2*t,t能取到0-sum/2之间所有的值,则此时也可以得到所有的奇数N,

  同理,当答案的路径在左数第二支时,设sum=2^k,t同上,则N=sum-2*t,t能取到0-sum/2之间所有的值,则此时可以得到所有的偶数N。

  此时,设s=sum-N,若s%2==0,则可以直接求取路径,若s为奇数,则sum++后求取。

代码如下:

 1 #include<cstdio>
 2 
 3 using namespace std;
 4 
 5 int main(){
 6     int t,n,k;
 7     long long ha,tp=1;
 8     scanf("%d",&t);
 9     for(int i=1;i<=t;i++){
10         scanf("%d%d",&n,&k);
11         printf("Case #%d:\n",i);
12         ha=1;
13         ha<<=k;
14         ha-=1;
15         ha-=n;
16         if(ha%2==0){
17             ha/=2;
18             for(int i=0;i<k;i++){
19                 if(ha&(1<<i)){
20                     printf("%I64d -\n",(tp<<i));
21                 }
22                 else printf("%I64d +\n",(tp<<i));
23             }
24         }
25         else {
26             ha++;
27             if(!(ha&(1<<(k-1)))){
28                 ha/=2;
29             for(int i=0;i<k-1;i++){
30                 if(ha&(1<<i)){
31                     printf("%I64d -\n",(tp<<i));
32                 }
33                 else printf("%I64d +\n",(tp<<i));
34             }
35             printf("%d +\n",(1<<(k-1))+1);
36             }
37             else {
38                 long long ha2=ha-2;
39                 ha2/=2;
40                 for(int i=0;i<(k-1);i++)
41                     if(ha2&(1<<i))
42                         printf("%I64d +\n",(tp<<i));
43                     else printf("%I64d +\n",(tp<<i));
44                 printf("%I64d -\n",(tp<<(k-1))+1);
45             }
46         }
47     }
48     return 0;
49 }

 

 

posted @ 2019-10-20 21:23  xxmlala  阅读(42)  评论(0编辑  收藏