无法解决:CodeForces(TwoButtons,520B)使用二叉树

时间:2015-11-26 13:33:21

标签: c++ c++11 binary-tree

我一直试图通过使用二叉树来解决这个问题,因为我开始了解它们。 请告诉我这个问题是否可以通过使用二进制树来解决,如果是,那我到目前为止编写的代码有什么问题(在c ++中)? 它给出了错误的答案......

问题: 瓦西亚找到了一个奇怪的装置。在设备的前面板上有:红色按钮,蓝色按钮和显示正整数的显示。单击红色按钮后,设备将显示的数字乘以2。单击蓝色按钮后,设备会从显示屏上的数字中减去一个。如果在某个时刻该数字停止为正数,则设备会发生故障。显示器可以显示任意大的数字。最初,显示屏显示数字n。

鲍勃希望在显示屏上显示数字m。为了达到这个结果,他必须达到的最小点击次数是什么?

输入 输入的第一行和唯一一行包含两个不同的整数n和m(1≤n,m≤104),用空格分隔。

输出 打印一个数字 - 需要按下按钮才能获得数字m的数量n的最小次数。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <stack>
#include <queue>
using namespace std;

struct Node{
    int val;
    Node* Left;
    Node* Right;
};

Node* GetNode(int val){
    Node* newnode = new Node();
    newnode->val = val;
    newnode->Left = NULL;
    newnode->Right = NULL;
    return newnode;
}

int BFS(Node* root, int m){
    int ctr = 0;
    queue<Node*> qu;
    qu.push(root);
    while(!qu.empty()){
        Node* tmp = qu.front();
        qu.pop();
        if(tmp->val == m) return ctr;
        ctr++;
        if(tmp->Left != NULL) qu.push(tmp->Left);
        if(tmp->Right != NULL) qu.push(tmp->Right);
    }
}

int main(void){
    int n, m;
    scanf("%d%d", &n, &m);
    Node* root = GetNode(n);
    Node* tmp;
    queue<Node*> qu;
    qu.push(root);
    while(!qu.empty()){
        tmp = qu.front();
        qu.pop();
        if(tmp->val == m) break;
        tmp->Left = GetNode(2 * tmp->val);
        qu.push(tmp->Left);
        if(tmp->val-1 >= 0){
            tmp->Right = GetNode(tmp->val - 1);
            qu.push(tmp->Right);
        }
    }
    printf("%d\n", BFS(root, m));
}

2 个答案:

答案 0 :(得分:0)

while中的main()循环是一个无限循环。没有条件会终止该循环。你的程序不断为队列分配内存,直到它用完空间。

您的continue应该是break。尽管如此,由于它生成的指数级增长的队列,这个while()循环的效率非常低。

答案 1 :(得分:0)

您需要存储节点的级别(根级别:0),因为这将为您提供获取m所需的步骤。

struct Node{
int val;
Node* Left;
Node* Right;
int lev;
};

然后,getNode将再增加一个参数(级别):

Node* GetNode(int val,int l){
Node* newnode = new Node();
newnode->val = val;
newnode->lev = l;
newnode->Left = NULL;
newnode->Right = NULL;
return newnode;
}

树的根从0级开始:

Node* root = GetNode(n,0);

当你想得到一个新节点时,该等级将是父+1的级别:

node->Left = GetNode(value,(node->lev)+1);

你的休息时间不是最有效的,你应该在添加一个新节点时停止循环(值为tmp-> val * 2或tmp-> val-1),其中任何一个都是m(并且不要忘记更新tmp,你将用它来打印答案)。

使算法高效的另一个重要方面是知道应该在树中何时添加节点。其中一个是“如果它们是tmp-&gt; val-1小于或等于0(数字必须始终为正)。另外,如果节点高于m,那么它不应该增加,所以tmp-&gt ;只有在tmp-&gt; val&lt; m。

时才会创建left

最后,如果你到达树中已有的数字,那么你应该添加该节点(这个验证是用!nit.count(x)完成的,这意味着“如果我的地图中没有任何x”)

//this if comes inmediatly after reading n and m
if (n==m){
    cout<<0<<endl;
    return 0;
}
while(!qu.empty()){
    tmp = qu.front();
    qu.pop();
    if (!nit.count(2 * tmp->val) && (tmp->val<m)){
        tmp->Left = GetNode(2 * tmp->val,tmp->lev+1);
        //cout<<2 * tmp->val<<endl;
        if ((2 * tmp->val)==m){
            tmp=tmp->Left; break;
        }
        nit[2 * tmp->val]++;
        qu.push(tmp->Left);
    }
    if(!nit.count(tmp->val-1) && (tmp->val-1 > 0)){
        tmp->Right = GetNode(tmp->val - 1,tmp->lev+1);
        //cout<<tmp->val-1<<endl;
        if ((tmp->val-1)==m){
            tmp=tmp->Right; break;
        }
        nit[tmp->val-1]++;
        qu.push(tmp->Right);
    }
}

现在你有了答案:

printf("%d\n",tmp->lev);

这是整个代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <map>
#include <stack>
#include <queue>
using namespace std;

struct Node{
    int val;
    Node* Left;
    Node* Right;
    int lev;
};

Node* GetNode(int val,int l){
    Node* newnode = new Node();
    newnode->val = val;
    newnode->lev = l;
    newnode->Left = NULL;
    newnode->Right = NULL;
    return newnode;
}


int main(void){
    int n, m;
    map<int,int>nit;
    scanf("%d%d", &n, &m);
    if (n==m){
        cout<<0<<endl;
        return 0;
    }
    Node* root = GetNode(n,0);
    nit[n++];
    Node* tmp;
    queue<Node*> qu;
    qu.push(root);

    while(!qu.empty()){
        tmp = qu.front();
        qu.pop();
        if (!nit.count(2 * tmp->val) && (tmp->val<m)){
            tmp->Left = GetNode(2 * tmp->val,tmp->lev+1);
            //cout<<2 * tmp->val<<endl;
            if ((2 * tmp->val)==m){
                tmp=tmp->Left; break;
            }
            nit[2 * tmp->val]++;
            qu.push(tmp->Left);
        }
        if(!nit.count(tmp->val-1) && (tmp->val-1 > 0)){
            tmp->Right = GetNode(tmp->val - 1,tmp->lev+1);
            //cout<<tmp->val-1<<endl;
            if ((tmp->val-1)==m){
                tmp=tmp->Right; break;
            }
            nit[tmp->val-1]++;
            qu.push(tmp->Right);
        }
    }
    printf("%d\n",tmp->lev);
}

对不起我的英语c: