(表示式樹)【UVa-12219】Common Subexpression Elimination
阿新 • • 發佈:2018-12-11
陣列開小了RE了一發,日常膜LRJ.
學到倆知識點,一個是結構體作為map或set的key時,需過載<運算子。第二個是直接判斷done[v]==T可以避免一次memset,優化時間。
/* * @Author: SamsonHo * @Date: 2018-09-20-12.48.32 * @URL:https://vjudge.net/problem/UVA-12219 */ #include<bits/stdc++.h> #define INF 0x3f3f3f3f using namespace std; typedef long long LL; const int MAXN = 1e5+10; int T,done[MAXN],cnt; char str[3*MAXN],*p; struct Node { string s; int h,left,right; bool operator < (const Node& rhs) const { if(h != rhs.h) return h < rhs.h; if(left != rhs.left) return left < rhs.left; return right < rhs.right; } }node[MAXN]; map<Node,int> dict; int solve() { int id = cnt++; Node& u = node[id]; u.left = u.right = -1; u.s = ""; u.h = 0; while(isalpha(*p)) { u.h = u.h*27+*p-'a'+1; u.s.push_back(*p); ++p; } if(*p == '(') { ++p; u.left = solve(); ++p; u.right = solve(); ++p; } if(dict[u] != 0) { --cnt; --id; return dict[u]; } return dict[u] = id; } void print(int v) { if(done[v] == T) { printf("%d",v+1); //避免memset } else { done[v] = T; printf("%s",node[v].s.c_str()); if(node[v].left != -1) { putchar('('); print(node[v].left); putchar(','); print(node[v].right); putchar(')'); } } } int main(void) { scanf("%d",&T); while(T--) { dict.clear(); cnt = 0; scanf("%s",str); p = str; print(solve()); puts(""); } }