遥控车
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.