题目:
平平带着韵韵来到了游乐园,看到了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 是唯一确定的。一辆车可以玩多次。
分析:
第二问我们可以在纸上演算后,得出是斐波那契数列,但是由于数据大,所以要用高精加。而第一问暴力寻找会超时,所以选用更优的二分查找算法。
附上代码:
const maxn=10000; var n,m,ans,len:longint; s:array [0..maxn] of string; s1:string; a,b,c:array [0..maxn] of longint; procedure gjj; var i,bj:longint; begin bj:=0; fillchar(c,sizeof(c),0); for i:=1 to len+1 do begin c[i]:=c[i]+a[i]+b[i]+bj; bj:=c[i] div 10; c[i]:=c[i] mod 10; end; if c[len+1]>0 then inc(len); for i:=1 to len do a[i]:=b[i]; for i:=1 to len do b[i]:=c[i]; end; procedure qsort(l,r:longint); var i,j:longint; mid,k:string; begin i:=l; j:=r; mid:=s[(l+r) shr 1]; repeat while s[i]<mid do inc(i); while s[j]>mid do dec(j); if i<=j then begin k:=s[i]; s[i]:=s[j]; s[j]:=k; inc(i); dec(j); end; until i>j; if l<j then qsort(l,j); if i<r then qsort(i,r); end; procedure init; var i:longint; begin readln(n,m); a[1]:=1; b[1]:=2; len:=1; for i:=1 to n do readln(s[i]); for i:=3 to n do gjj; end; function find(s2:string):boolean; var l,r,mid:longint; begin find:=false; l:=1;r:=n;mid:=(l+r) shr 1; while l<=r do begin mid:=(l+r) shr 1; if pos(s2,s[mid])=1 then exit(true); if s2<s[mid] then r:=mid-1 else l:=mid+1; end; end; procedure main; var i,j:longint; begin qsort(1,n); for i:=1 to m do begin readln(s1); if find(s1) then inc(ans); end; writeln(ans); for i:=len downto 1 do write(c[i]); end; begin //assign(input,'find.in');reset(input); //assign(output,'find.out');rewrite(output); init; main; //close(input);close(output); end.