• 复读


     

    题目描述

    小 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 }
  • 相关阅读:
    【存储数据恢复】EMC某型号存储raid5崩溃的数据恢复案例
    【服务器数据恢复】Unix环境zfs文件系统下重组RAID5案例分享
    【服务器数据恢复】Raid5阵列两块硬盘亮黄灯掉线的数据恢复案例
    【服务器数据恢复】浪潮服务器硬盘坏道导致raid5瘫痪的数据恢复案例
    【服务器数据恢复】5盘RAID5中4块盘重建RAID5后原RAID5的数据恢复案例
    【存储数据恢复】IBM存储文件系统损坏的数据恢复案例
    我疯了?
    修身养性, 可持续发展_613
    懂得沉淀, 明白舍得, 张弛有度, 次第花开
    两年
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/11756054.html
Copyright © 2020-2023  润新知