遥控车

9 篇文章 0 订阅
4 篇文章 0 订阅

遥控车

Time Limits: 1000 ms Memory Limits: 65536 KB

Description
平平带着韵韵来到了游乐园,看到了n辆漂亮的遥控车,每辆车上都有一个唯一的名字name[i]。韵韵早就迫不及待地想玩名字是s的遥控车。可是韵韵毕竟还小,她想象的名字可能是一辆车名字的前缀(也就是说能确定一个i,使s是name[i]的前缀),这时她就能玩第i辆车;或者是一个无中生有的名字,即s不是任何一辆车名字的前缀,这时候她什么也不能玩。
你需要完成下面的任务:
1.韵韵想了m个她想要的名字,请告诉她能玩多少次。
2.由于管理员粗心的操作,导致每辆车的摆放位置都可能出现微小的差错,原来第i辆车现在的位置可能是i-1、i、i+1中的任意一个(第1辆车的位置不可能是0,第n辆车的位置不可能是n+1)。请你计算出共有多少种可能的排列。
注:数据保证当s是name[i]的前缀时,i是唯一确定的。一辆车可以玩多次。

Input
第一行是2个正整数n、m。
接下来n行,每行1个字符串name[i],表示第i辆车的名字。
接下来m行,每行1个字符串s,表示韵韵想要的名字。

Output
第一行输出韵韵能玩的次数。
第二行输出共有多少种可能的排列。

Sample Input

4 4
Abcd
DeF
AAa
aBccc
Ab
AA
AbC
aBcc

Sample Output

3
5

Hint
【数据规模和约定】
对于题目涉及到的字符串严格区分大小写,且长度小于255。
对于20%的数据 n≤10,m≤10;
对于40%的数据 n≤1000,m≤1000;
对于100%的数据 n≤10000,m≤10000。


解题思路

这题建议用pascal
首先将字符串排序。
第一问二分符合条件的字符串的起终位置x->y,再将f[x]加一,f[y+1]减一,最后线性扫一遍,如果f[i]>0,答案加一。(我只是怕会有重复而已)

第二问仔细看是一个以1,2开头的斐波纳茨数列的第n个数,既然n=10000,那就说明要用高精度,不过不知道需不需要压位,反正我是压了16位。

Codes:

const maxn=10000000000000000;
var a:Array[0..10000]of string;
    n,m,i,tot,x,y:longint;
    kind:array[0..10001]of longint;
    f:array[0..2,0..1000]of int64;
procedure p(h,t:longint);
    var l,r:longint;
        m:string;
begin
    l:=h;r:=t;m:=a[(h+t)>>1];
    repeat
        while a[l]<m do inc(l);
        while a[r]>m do dec(r);
        if l<=r then
        begin
            a[0]:=a[l];a[l]:=a[r];a[r]:=a[0];
            inc(l);dec(r);
        end;
    until l>r;
    if h<r then p(h,r);
    if l<t then p(l,t);
end;
procedure can();
    var h,t,m:longint;
begin
    h:=1;t:=n;
    x:=h;
    while h<=t do
    begin
        m:=(h+t)>>1;
        if pos(a[0],a[m])=1 then
        begin
            x:=m;
            t:=m-1;
        end else
            if a[0]<a[m] then
            begin
                x:=m;
                t:=m-1;
            end else
            begin
                h:=m+1;
            end;
    end;
    if pos(a[0],a[h])<>1 then
    begin
        x:=0;y:=0;exit;
    end;
    h:=1;t:=n;
    y:=t;
    while h<=t do
    begin
        m:=(h+t)>>1;
        if pos(a[0],a[m])=1 then
        begin
            y:=m;
            h:=m+1;
        end else
            if a[0]>a[m] then
            begin
                y:=m;
                h:=m+1;
            end else
            begin
                t:=m-1;
            end;
    end;
end;
procedure add;
    var i,x:longint;
begin
    if f[1,0]>f[0,0] then x:=f[1,0] else x:=f[0,0];
    for i:=1 to x do
    begin
        f[2,i]:=f[2,i]+f[1,i]+f[0,i];
        f[2,i+1]:=f[2,i]div maxn;
        f[2,i]:=f[2,i]mod maxn;
    end;
    if f[2,x+1]>0 then f[2,0]:=x+1 else f[2,0]:=x;
end;
procedure turn(num:int64);
    var s:string;
begin
    str(num,s);
    while length(s)<16 do s:='0'+s;
    write(s);
end;
begin
    readln(n,m);
    for i:=1 to n do readln(a[i]);
    p(1,n);
    for i:=1 to m do
    begin
        readln(a[0]);
        can();
        inc(kind[x]);dec(kind[y+1]);
    end;
    for i:=1 to n do
    begin
        inc(kind[i],kind[i-1]);
        if kind[i]>0 then inc(tot);
    end;
    writeln(tot);
    if(n=1)or(n=2)then
    begin
        writeln(n);
    end else
    begin
        f[0,0]:=1;f[0,1]:=1;
        f[1,0]:=1;f[1,1]:=2;
        for i:=3 to n do
        begin
            add;
            f[0]:=f[1];
            f[1]:=f[2];
            fillchar(f[2],sizeof(f[2]),0);
        end;
        write(f[1,f[1,0]]);
        for i:=f[1,0]-1 downto 1 do turn(f[1,i]);
    end;
end.
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值