Trees on the level UVA - 122 找规律模拟题,不需要结构体建树

题目链接

在这里插入图片描述
分析:刘老师的方法是动态建树,模拟bfs来层序遍历。”投机取巧“这道题也可以ac,找规律即可。

思路:定义一个map<string, int, MyCompare> binary;

  • string为括号中的LL,RR等等
  • int为结点的值
  • 自定义排序:我们可以发现规律,本题的输入已经将给我们输入了一个二叉树,不需要再建树了。从上到下,左到右LL,LLR除了长度以外已经符合字典序了,长度需要自定义排序。看图:
    在这里插入图片描述

所以在map中的顺序即为层序。顺便map可以查重。

再定义一个set里面存储每个结点再二叉树中的编号,用count()来判断是否它的父结点存在。

代码:

#include <bits/stdc++.h>
using namespace std;

class MyCompare {
public:
    bool operator () (const string& k1, const string& k2) const {
        if(k1.length()==k2.length()) return k1<k2;
        else return k1.length()<k2.length();
    }
};

map<string, int, MyCompare> binary;
set<int, greater<int> > arr;

void split(string str, bool &flag) {
    if(str.find('L')==string::npos && str.find('R')==string::npos) {
        stringstream s(str.substr(1,str.find(',')-1));
        int num; s >> num;
        if(binary.count("A")) { flag = false; return; }
        binary["A"] = num;
        arr.insert(1);
    }
    else {
        stringstream s(str.substr(1,str.find(',')-1));
        int num; s >> num;
        string t = str.substr(str.find(',')+1);
        t.erase(t.length()-1);
        if(binary.count(t)) { flag = false; return ; }
        binary[t] = num;
        int index = 1;
        for (char i : t) {
            if(i =='R') index = index*2+1;
            else index *= 2;
        }
        arr.insert(index);
    }
}

void Judge(bool &flag) {
    for(auto it=arr.begin(); it!=arr.end(); it++) {
        int father = (*it)/2;
        if(arr.count(father)==0 && (*it)!=1) flag = false;
    }
}

int main() {
    freopen("i.txt","r",stdin);
    string str;
    bool flag = true;
    while(cin >> str) {
        if (str == "()") {
            Judge(flag);
            if (!flag) cout << "not complete" << endl;
            else {
                bool b = true;
                for (auto &it : binary) {
                    if (b) { cout << it.second; b = false; }
                    else cout << " " << it.second;
                }
                cout << endl;
            }
            flag = true;
            binary.clear();
            arr.clear();
        } else split(str, flag);
    }
}

刘老师方法自己也写了一遍,思路很清晰,也要熟练掌握。

#include <bits/stdc++.h>
using namespace std;
typedef struct Bitnode *Bitree;
struct Bitnode {
    bool have_value;
    int data;
    Bitree left, right;
    Bitnode() :
        have_value(false), left(nullptr), right(nullptr) {}
};
vector<int> vector1;
Bitree bitree;
bool failed;

void Build(string str) {
    Bitree p = bitree;
    int num;
    stringstream s(str.substr(1,str.find(',')-1));
    s >> num;
    string t = str.substr(str.find(',')+1);
    t.erase(t.length()-1);
    for (char i : t) {
        if(i =='L') {
            if(!p->left) p->left = new Bitnode();
            p = p->left;
        }
        else if(i =='R') {
            if(!p->right) p->right = new Bitnode();
            p = p->right;
        }
    }
    if(p->have_value) failed = true;
    p->data = num;
    p->have_value = true;
}

void bfs() {
    bool flag = true;
    queue<Bitree> queue1;
    queue1.push(bitree);
    while(!queue1.empty()) {
        Bitree temp = queue1.front();
        if(!temp->have_value) { failed = true; return; }
        queue1.pop();
        if(temp->left) queue1.push(temp->left);
        if(temp->right) queue1.push(temp->right);
        vector1.push_back(temp->data);
    }
}

void remove_tree(Bitree b) {
    if(b==nullptr) return;
    remove_tree(b->left);
    remove_tree(b->right);
    delete b;
}

int main() {
    freopen("i.txt","r",stdin);
    string str;
    bitree = new Bitnode();
    while(cin >> str) {
        if(str=="()") {
            bfs();
            if(failed) cout << "not complete" << endl;
            else {
                cout << vector1[0];
                for(int i = 1; i < vector1.size(); i++)
                    cout << " " << vector1[i];
                cout << endl;
            }
            vector1.clear();
            remove_tree(bitree);
            bitree = new Bitnode();
            failed = false;
        }
        else Build(str);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值