题目链接:https://vjudge.net/problem/UVA-12219
数组开小了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("");
}
}