看来以后用pascal的函数要小心了;
简简单单pos其实时间复杂度是二次方级的……
今天学习的是KMP——字符匹配算法;
这两道题也都很简单,都是为这个算法练手的,
最朴素的匹配显然是穷举起始位置然后看是否匹配,复杂度O(nm)不尽人意
kmp的思想就是尽可能利用之前匹配的信息进行匹配。
具体分析我就不讲了,传送门http://www.cppblog.com/oosky/archive/2006/07/06/9486.html讲的很详细
但据说这两题暴力都可过……
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 var a:array[0..105] of string; 2 next:array[0..105] of integer; 3 f:array[0..105] of boolean; 4 s:string; 5 c:char; 6 i,j,l,t,p,v,n,w:integer; 7 procedure work_next(s:string); 8 var i:integer; 9 begin 10 fillchar(next,sizeof(next),0); 11 i:=1; 12 j:=0; 13 next[1]:=0; 14 while i<=l do 15 begin 16 if (j=0) or (s[i]=s[j]) then 17 begin 18 inc(i); 19 inc(j); 20 next[i]:=j; 21 end 22 else j:=next[j]; 23 end; 24 end; 25 function compare(a,b:string):boolean; 26 var i,j,l1:integer; 27 begin 28 i:=1; 29 j:=1; 30 l1:=length(a); 31 while (i<=l1) and (j<=l) do 32 begin 33 if (j=0) or (a[i]=b[j]) then 34 begin 35 inc(i); 36 inc(j); 37 end 38 else j:=next[j]; 39 end; 40 if j>l then exit(true) else exit(false); 41 end; 42 43 procedure kmp; 44 var j:integer; 45 begin 46 for j:=1 to n do 47 begin 48 if (j=v) or f[j] then continue; 49 if (compare(a[j],s)) then 50 begin 51 f[j]:=true; 52 w:=w+1; 53 end; 54 end; 55 end; 56 57 begin 58 readln(t); 59 for p:=1 to t do 60 begin 61 readln(n); 62 v:=0; 63 for i:=1 to n do 64 begin 65 readln(a[i]); 66 if (v=0) or (length(a[i])<length(a[v])) then v:=i; 67 end; 68 for l:=length(a[v]) downto 1 do 69 begin 70 for i:=1 to length(a[v])-l+1 do 71 begin 72 w:=1; 73 fillchar(f,sizeof(f),false); 74 s:=copy(a[v],i,l); 75 work_next(s); 76 kmp; 77 for j:=1 to l div 2 do 78 begin 79 c:=s[j]; 80 s[j]:=s[l-j+1]; 81 s[l-j+1]:=c; 82 end; 83 work_next(s); 84 kmp; 85 if w=n then break; 86 end; 87 if w=n then break; 88 end; 89 if w=n then writeln(l) else writeln(0); 90 end; 91 end.