HDU - 5573 Binary Tree

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chenshibo17/article/details/83012555

The Old Frog King lives on the root of an infinite tree. According to the law, each node should connect to exactly two nodes on the next level, forming a full binary tree. 

Since the king is professional in math, he sets a number to each node. Specifically, the root of the tree, where the King lives, is 11. Say froot=1froot=1. 

And for each node uu, labels as fufu, the left child is fu×2fu×2 and right child is fu×2+1fu×2+1. The king looks at his tree kingdom, and feels satisfied. 

Time flies, and the frog king gets sick. According to the old dark magic, there is a way for the king to live for another NN years, only if he could collect exactly NNsoul gems. 

Initially the king has zero soul gems, and he is now at the root. He will walk down, choosing left or right child to continue. Each time at node xx, the number at the node is fxfx (remember froot=1froot=1), he can choose to increase his number of soul gem by fxfx, or decrease it by fxfx. 

He will walk from the root, visit exactly KK nodes (including the root), and do the increasement or decreasement as told. If at last the number is NN, then he will succeed. 

Noting as the soul gem is some kind of magic, the number of soul gems the king has could be negative. 

Given NN, KK, help the King find a way to collect exactly NN soul gems by visiting exactly KK nodes.

Input

First line contains an integer TT, which indicates the number of test cases. 

Every test case contains two integers NN and KK, which indicates soul gems the frog king want to collect and number of nodes he can visit. 

⋅⋅ 1≤T≤1001≤T≤100. 

⋅⋅ 1≤N≤1091≤N≤109. 

⋅⋅ N≤2K≤260N≤2K≤260.

Output

For every test case, you should output " Case #x:" first, where xx indicates the case number and counts from 11. 

Then KK lines follows, each line is formated as 'a b', where aa is node label of the node the frog visited, and bb is either '+' or '-' which means he increases / decreases his number by aa. 

It's guaranteed that there are at least one solution and if there are more than one solutions, you can output any of them. 
 

Sample Input

2
5 3
10 4

Sample Output

Case #1:
1 +
3 -
7 +
Case #2:
1 +
3 +
6 -
12 +

       这是一道思维题差不多的吧,一个向下延伸的二叉树,问能否在b步的限制下获得a的总价值~~;

       我们可以注意得到的是2^b>=a,也就是说b与二进制下的a有关~~

       于是我们可以从常理上推得到,只要从1 2 4 8 16这样的从最左边走,一定能够在n(2^n刚好>=a)的步数下到达。如果a是2的幂的话,最后一步只要走右边那条路就好了。

        而如果多余的步数我们可以吧最后一步的(+)改为减(可以得出一定是+),然后向这个最后一步的两倍的下方延伸。

扫描二维码关注公众号,回复: 3686887 查看本文章

比如最后一步是+15,我们可以把多余的步数(假如多3步)改为-15 -30 -60 +120.这样的话,就能完美抵消多余步数的影响了。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
#define ll long long int
ll a,b;
ll su[70];
bool check(){
    su[0]=1;
    for(int i=1;i<=62;i++){
        su[i]=su[i-1]*2;
    }
}
int main(){
    int te;
    cin>>te;
    check();
    for(int cas=1;cas<=te;cas++){
        printf("Case #%d:\n",cas);
        cin>>a>>b;
        if(a==1&&b==1){
            cout<<"1 +"<<'\n';
            continue;
        }
        int mi=lower_bound(su+0,su+62,a)-su;
      //  cout<<mi<<endl;
        if(su[mi]==a){
            queue<char>q;queue<ll>qu;
            ll now=1;
            for(int i=1;i<mi;i++){
                qu.push(now);
                q.push('+');
                now*=2;
            }
            for(int i=mi;i<b;i++){
                qu.push(now);
                q.push('-');
                now*=2;
            }
            qu.push(now+1);
            q.push('+');
            while(!q.empty()){
                cout<<qu.front()<<" ";
                cout<<q.front()<<"\n";
                qu.pop();
                q.pop();
            }
        }
        else{
            ll now=1;
            ll md=su[mi]-a;
      //      cout<<md<<endl;
            int spot=md%2;md/=2;
            queue<char>q;queue<ll>qu;
            for(int i=1;i<mi;i++){
                qu.push(now);
                if(md%2)q.push('-');
                else q.push('+');
                now*=2;
                md/=2;
            }
            if(spot==0)
                now+=1;
            for(int i=mi;i<b;i++){
                qu.push(now);
                q.push('-');
                now*=2;
            }
            qu.push(now);
            q.push('+');
            while(!q.empty()){
                cout<<qu.front()<<" ";
                cout<<q.front()<<"\n";
                qu.pop();
                q.pop();
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/chenshibo17/article/details/83012555
今日推荐