题目描述
小 X 捡到了一台复读机,这台复读机可以向机器人发号施令。机器人将站在一棵完全二叉树的根上,完全二叉树是无限延伸的。你将向复读机录入一串指令,这串指令单个字符可以是:
L:命令机器人向当前节点的左子走;R:命令机器人向当前节点的右子走;U:命令机器人向当前节点的父亲走(若没有,则命令非法)。
录入指令后,复读机将会把指令无限复读下去。比如命令为 LR,那么机器人会遵从 LRLRLRLR... 一直走下去。
这棵完全二叉树上有一个 nnn 个节点的连通块,保证这个连通块包含根节点。连通块上的每个节点都埋有宝藏,机器人到达过的地方如果有宝藏,则会将其开采。如果一个地方没有宝藏,机器人也可以到那里去。机器人也可以反复经过一个地方。
显然,这个连通块本身也是一棵二叉树。
现在,有人告诉了小 X 埋有宝藏的这棵二叉树的前序遍历,小 X 需要寻找到一条尽量短的指令,使得机器人能够挖掘出所有宝藏。
输入格式
一行一个字符串,由 0123 中的字符组成,表示埋有宝藏的这棵二叉树的前序遍历。
0:表示这是一个没有儿子的节点。1:表示这是一个只有左子的节点。2:表示这是一个只有右子的节点。3:表示这是一个既有左子又有右子的节点。
输出格式
一个整数,表示最短指令的长度。
输入输出样例
输入 #1
1313000
输出 #1
3
输入 #2
333003003300300
输出 #2
15
说明/提示
【样例 1 说明】
一种可行的最短指令为 LRU
- Subtask 1(31 points):2≤n≤10^2
- Subtask 2(32 points):2≤n≤200
- Subtask 3(37 points):无特殊限制。
对于 100%100\%100% 的数据,2≤n≤2×10^3
学业繁忙,题解先欠着。。。
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<algorithm>
5 #include<cmath>
6 using namespace std;
7 struct Tree_
8 {
9 int l,r,size;
10 }Tree[5005],c[5005];
11 int dep[5005],pa[5005],n,num,ans;
12 char s[5005];
13 void build(int x,int fa)
14 {
15 dep[x]=dep[fa]+1;Tree[x].size=1;
16 pa[x]=fa;
17 if (s[x-1]=='0') return;
18 if (s[x-1]=='1')
19 {
20 Tree[x].l=x+1;
21 build(x+1,x);
22 Tree[x].size+=Tree[Tree[x].l].size;
23 }
24 if (s[x-1]=='2')
25 {
26 Tree[x].r=x+1;
27 build(x+1,x);
28 Tree[x].size+=Tree[Tree[x].r].size;
29 }
30 if (s[x-1]=='3')
31 {
32 Tree[x].l=x+1;
33 build(x+1,x);
34 Tree[x].size+=Tree[Tree[x].l].size;
35 Tree[x].r=x+Tree[x].size;
36 build(x+Tree[x].size,x);
37 Tree[x].size+=Tree[Tree[x].r].size;
38 }
39 //cout<<x<<' '<<Tree[x].l<<' '<<Tree[x].r<<endl;
40 }
41 int merge(int rt,int now,int goal)
42 {
43 if (!now) return rt;
44 if (!rt) rt=++num;
45 c[rt].size=1;
46 if (now==goal) return rt;
47 c[rt].l=merge(c[rt].l,Tree[now].l,goal);
48 c[rt].size+=c[c[rt].l].size;
49 c[rt].r=merge(c[rt].r,Tree[now].r,goal);
50 c[rt].size+=c[c[rt].r].size;
51 return rt;
52 }
53 int find(string opt)
54 {int i;
55 int now=1,lst=0,len=opt.size();
56 while (now)
57 {
58 lst=now;
59 for (i=0;i<len;i++)
60 {
61 if (opt[i]=='L') now=Tree[now].l;
62 else now=Tree[now].r;
63 if (!now) break;
64 }
65 merge(1,lst,now);
66 }
67 return c[1].size;
68 }
69 void dfs(int x,string opt)
70 {int cnt=0;
71 if (!x) return;
72 if (x!=1)
73 {
74 memset(c,0,sizeof(c));
75 num=1;
76 cnt=find(opt);
77 ans=min(ans,2*(cnt-1)-dep[x]+1);
78 }
79 dfs(Tree[x].l,opt+'L');
80 dfs(Tree[x].r,opt+'R');
81 }
82 int main()
83 {
84 cin>>s;
85 n=strlen(s);
86 build(1,0);
87 ans=2e9;
88 dfs(1,"");
89 cout<<ans;
90 }