二叉树

来源:互联网 发布:乐乎网络电话 编辑:程序博客网 时间:2024/06/09 18:35

题目

在一个无穷的满二叉树中,有以下几个特点:
  (1) 每个节点都有两个儿子——左儿子和右儿子;
  (2) 如果一个节点的编号为X,则它的左儿子编号为2X,右儿子为2X+1;
  (3) 根节点编号为1。
  现在从根结点开始走,每一步有三种选择:走到左儿子、走到右儿子和停在原地。
  用字母“L”表示走到左儿子,“R”表示走到右儿子,“P”表示停在原地,用这三个字母组成的字符串表示一个明确的行走路线。
一个明确的行走路线的价值为最终到达节点的编号,例如LR的价值为5,而RPP的价值为3。
  我们用字符“L”、“R”、“P”和“”组成的字符串表示一组行走路线,其中“”可以是“L”、“R”、“P”中的任意一种,所有跟这个行走路线匹配的字符串都认为是可行的。
  例如L*R包含LLR、LRR和LPR。而**包含LL、LR、LP、RL、RR、RP、PL、PR和PP这9种路线。
  一组行走路线的价值等于所有匹配该模式的路线的价值之和。请你编程计算给定路线的价值。

样例输入:
输入一个字符串表示一组行走路线,里面只含有“L”、“R”、“P”和“*”四种字符,长度不会超过10000。
输入1:
P*P
输入2:
LLLLLRRRRRLLLLLRRRRRLLLLLRRRRRLLLLL

样例输出:
输出该路线的价值。
输出1:
6
输出2:
35400942560

【数据范围】
 30%的数据满足路线中不含“*”;
 50%的数据满足最多只有3个“*”。


思路:呵呵,似乎没有什么算法,直接模拟找规律- -|||、


解法:
面对“L”,就是把ans* 2。面对“R”,就是ans*2+1。面对“P”,就是不变啦。
面对“* ”,就有些麻烦,因为 “*”是可以变化为任意一个字母,所以要分成三种情况,所以上述三种情况每种都要进行一次。
然而我发现,经过“* ”后,后面面对“R”会有些麻烦。
每次经历过“ * ”号时,就是将原有的答案复制三份,每一份逐个对应三个字母进行计算,那么后来面对“R”时,我们只需要额外加上一个3 *(星号的数量)就可以了。这里可能有些难理解,自己在草稿纸上推一推。
当然,因为字符串高达10000位,所以要压位高精度。


代码:

type        arr=array[0..1003]of longint;const        mo=1000000000;var        a,b,c,d:arr;        s:ansistring;        i,j:longint;procedure        add(var a,b:arr);var        i,x:longint;begin        if a[0]>b[0] then i:=a[0] else i:=b[0];        x:=0;        for i:=1 to i do        begin                if i>a[0] then a[i]:=0;                if i>b[0] then b[i]:=0;                a[i]:=a[i]+b[i]+x;                x:=a[i] div mo;                a[i]:=a[i] mod mo;        end;        if x>0 then        begin                inc(i);                a[i]:=x;        end;        if i>a[0] then a[0]:=i;end;procedure        printf;var        s:string;        i:longint;begin        write(a[a[0]]);        for i:=a[0]-1 downto 1 do        begin                a[i]:=a[i]+mo;                str(a[i],s);                delete(s,1,1);                write(s);        end;end;begin       // assign(input,'T2.in'); reset(input);        readln(s);        a[0]:=1; a[1]:=1;        b[0]:=1; b[1]:=1;        d[0]:=1; d[1]:=1;        for i:=1 to length(s) do        begin                c[0]:=1; c[1]:=0;                if (s[i]='P')or(s[i]='*') then add(c,a);                if (s[i]='L')or(s[i]='*') then                begin                        add(c,a);                        add(c,a);                end;                if (s[i]='R')or(s[i]='*') then                begin                        add(c,a);                        add(c,a);                        add(c,b);                end;                if (s[i]='*') then                begin                        add(b,d);                        add(b,d);                end;                a:=c;                d:=b;        end;        printf;       // close(input);end.

这里写图片描述

0 0
原创粉丝点击