复读

 

题目描述

小 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 }

 

 

posted @ 2019-10-28 22:32  Z-Y-Y-S  阅读(271)  评论(1编辑  收藏  举报