接龙游戏
(words.pas/in/out)
Problem
给出n个单词,已经按长度排好了序.如果单词I是单词J的前缀,那么I- J算一次接龙.
你的任务是:对于输入的单词,找出最长的龙.
Input
数据第一行为n(1<=n<=100000),以下n行每行是一个单词(由小写组成),已经按长度排好了序.每个单词的长度不超过50.
Output
输出一行,这行为一个数,即最长的龙的长度.
Sample Input
5
i
a
int
able
inter
Sample Input
3
===================
这道题一测的时候,我全超时
那时我是直接用DP..并没有任何的排序..
----------------------------------------------------
其实这道题可以先按字典序排了之后再维护一个栈就可以了..
以后要记住了...
---------------------------------------------------------------------------------
考试时还想到了一种方法..==做..
建一棵树...
保证左子树并不是根点的后缀,右子树为根节点的后缀...
==============================================
var
n:longint;
s,s_z:array[1..100000]of string;
s_t:longint;
ans:longint;
// f:array[1..100000]of longint;
procedure init;
begin
assign(input,'words.in');
assign(output,'words.out');
reset(input); rewrite(output);
end;
procedure terminate;
begin
close(input); close(output);
halt;
end;
function pd(x,y:longint):boolean;
var
i:longint;
begin
pd:=true;
for i:=1 to length(s[x]) do
if s[x][i]<>s[y][i] then exit(false);
end;
procedure qsort(l,r:longint);
var
i,j:longint;
x,tem:string;
begin
i:=l; j:=r;
x:=s[(l+r)shr 1];
repeat
while x<s[j] do dec(j);
while s[i]<x do inc(i);
if i<=j then
begin
tem:=s[i];
s[i]:=s[j];
s[j]:=tem;
inc(i); dec(j);
end;
until i>j;
if i<r then qsort(i,r);
if l<j then qsort(l,j);
end;
function pd(s1,s2:string):boolean;
var
i:longint;
begin
pd:=true;
for i:=1 to length(s1) do
if s1[i]<>s2[i] then exit(false);
end;
procedure ru(i:longint);
begin
if s_t=0 then
begin
inc(s_t);
s_z[s_t]:=s[i];
if s_t>ans then ans:=s_t;
end
else
begin
while (s_t>=1) and not pd(s_z[s_t],s[i]) do dec(s_t);
inc(s_t);
s_z[s_t]:=s[i];
if s_t>ans then ans:=s_t;
end;
end;
procedure main;
var
i:longint;
begin
readln(n);
for i:=1 to n do
begin
readln(s[i]);
// f[i]:=1;
end;
qsort(1,n);
s_t:=0;
ans:=0;
for i:=1 to n do
begin
ru(i);
end;
writeln(ans);
end;
begin
init;
main;
terminate;
end.