hdu5573 B

题意:给定N和K,K是二叉树的层次,N是要做出的值。

从1开始走堆式二叉树,每次必须加或者减当前值,必须跑完K层。

要求找一条路可以经过K层得到N的数值。

思路:

尝试1、2、4、8 发现可以得出±1,±3,±5,±7,±9,±11,±13,±15。

尝试1、2、4、9发现可以得出±2,±4,±6,±8,±10,±12,±14,±16。

发现可以使用k层内,20、21、22、... ... 2k-1或者2k-1+1  得出 [1,2k] 内的所有数。

并且可以唯一确定关系,如

15=8+4+2+1,16=9+4+2+1

13=8+4+2-1,14=9+4+2-1

11=8+4-2+1,12=9+4-2+1

...

7=8-4+2+1,8=9-4+2+1

5=8-4+2-1,6=9-4+2-1
3=8-4-2+1,4=9-4-2+1
1=8-4-2-1,2=9-4-2-1

取数方式为:设定值0,若当前值小于N则加上当前节点值,若当前值大于N则减去当前节点值

综上,又因为限制条件 1N≤2k  在k层的表示范围 [1,2k内,

所以,可以通过2k 2k+1 这两个叶子节点向上取数,若N为奇则从2k 开始,若N为偶则2k+1 开始。

因为已知取数方式唯一确定,所以构造结束。

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define MAX 1000001
#define inf 0x3f3f3f3f
#define ll long long
#define MAX 1000001
const ll N = 2e5+7;
const ll mod = 1e9+7;
using namespace std;
ll n,k;
void dfs(ll u,ll c,ll sum){//当前节点 当前层 当前值  
    if(c==0){
        return ;
    }
    if(sum>n)    dfs(u/2,c-1,sum-u);
    else        dfs(u/2,c-1,sum+u);
    
    if(sum>n)    printf("%lld -
",u);
    else        printf("%lld +
",u);
}
int main(){
    int t;scanf("%d",&t);
    for (int cas=1;cas<=t;cas++){
        scanf("%lld%lld",&n,&k);
        printf("Case #%d:
",cas);
        int i=1<<(k-1);
        if(n%2==0)    i++;
        dfs(i,k,0);
    }
    return 0; 
}
View Code
原文地址:https://www.cnblogs.com/PdrEam/p/14530853.html