UVa 12219

来源:互联网 发布:博世配网工程设计软件 编辑:程序博客网 时间:2024/06/06 04:39

题意大体是给定一个字符串,根据字符串建树,然后可以把树化简成一个图,最后根据图输出一行字符串


思路

      映射


题目就是要求化简子树,使每一个子树都唯一存在,可以用一个三元组SubTree(root, l, r)代表整个子树,root是当前子树根的字符串,

l是当前子树的左子树,r是当前子树的右子树,每次用map查询可以实现O(logn)的查询,建树的时候直接从左到右扫描字符串,如果

当前字符是'(',则递归继续建树,否则则表示当前的子树已经构建完成,给每一个子树一个旧编号,用一个固定数组存下来,遍历的

时候用题目要求的新编号取代旧编号递归输出即可。

#include <bits/stdc++.h>using namespace std;const int maxn = 1000000 + 10;const int maxd = 50000 + 10;int nc;struct SubTree{    string root;    int l, r;    SubTree(){root = ""; l = r = 0;}    SubTree(string root, int l, int r) : root(root), l(l), r(r){}    bool operator < (const SubTree & rhs) const {        return root <rhs.root        || (root == rhs.root && l < rhs.l)        || (root == rhs.root && l == rhs.l && r < rhs.r);    }}subtree[maxd];map<SubTree, int> ID;int nID[maxn];bool isexp(char ch){    return ch == '(' || ch == ')' || ch == ',';}int pos;int build_tree(char * s){    SubTree st;    while(isalpha(s[pos])){        st.root.push_back(s[pos]);        pos++;    }    if(s[pos] == '('){        pos++;        st.l = build_tree(s);        st.r = build_tree(s);    }    pos++;    if(!ID.count(st)){        ID[st] = ++nc;        subtree[nc] = st;    }    return ID[st];}set<int> ss;void print(int root){    SubTree & st = subtree[root];    int id = ID[st];    if(!ss.count(id)){        printf("%s", st.root.c_str());        nID[id] = ++nc;        ss.insert(id);        if(st.l == 0 && st.r == 0) return;        putchar('('); print(st.l);        putchar(','); print(st.r);        putchar(')');    }else {        printf("%d", nID[id]);        return;    }}void solve(char * s){    int len = strlen(s);    pos = 0;    int root = build_tree(s);    nc = 0;    print(root); putchar('\n');}char s[maxn];void init(){    nc = 0;    ID.clear();    ss.clear();}int main(){    int n; scanf("%d", &n);    while(n --){        init();        scanf("%s", s);        solve(s);    }    return 0;}


0 0
原创粉丝点击