题目描述
小 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 }