Editorial for IOI '96 P5 - Longest Prefix
Submitting an official solution before solving the problem yourself is a bannable offence.
Let be a sequence of letters and let be a set of primitives. Denote by the set of sequences such that the following two conditions hold:
- is a prefix of a primitive in .
- for some . (For two sequences of letters and , we denote the concatenation of and by .)
It is obvious that can be composed from primitives in iff the empty sequence is in . Moreover, has an extension on the right that makes a composition of primitives in iff is non-empty. Therefore the following algorithm gives a solution to the task if DataFile contains the sequence to be examined.
Res:=0;
S:=empty; NoS:=1;
ReadLn(DataFile,X);
Slength:=1;
While (X<>'.') And (NoS>0) Do Begin
Append X to the end of S;
Q:=Suff(S,P);
NoS:=number of elements of Q;
If the empty sequence is element of Q Then Res:=Slength;
ReadLn(DataFile,X);
Inc(Slength);
End;
WriteOut(Res);
One obvious problem with this algorithm is that the data file is too large to read into the memory (unless you know how to use the machine's extra memory).
Fortunately, it is not necessary to read the whole sequence into memory. Let us observe that for a sequence and a letter can be computed from the set . Indeed, the following algorithm satisfies the requirement that if holds before executing then after the execution will hold.
Procedure Next(Q,X);
Begin
Q1:=empty;
Forall u in Q Do Begin
If ux is a prefix of some primitives in P Then
Begin
include ux in Q1;
If ux is equal to a primitive in P
Then include the empty sequence in Q1
End;
End;
Q:=Q1;
End;
In order to refine the algorithm , we have to answer the questions:
- Is a sequence a prefix of some primitive in ?
- Is a sequence equal to a primitive in ?
Consider the following data structure for the set of primitives .
Const
MaxN=100; (* maximum possible number of primitives *)
MaxL=20; (* maximum possible length of primitives *)
Var
P:Array[1..MaxN,1..MaxL] Of Char; (* array of primitives *)
L:Array[1..MaxN] Of Word; (* length of the primitives *)
Let us represent a sequence which is a prefix of a primitive in by the pair , such that the prefix of consisting of the first letters of the primitive equals , and is the least such index for . Note that the empty sequence is represented by the pair .
We can preprocess the set of primitives to build a transition table :
is if there is no primitive in with prefix , otherwise the least index such that is a prefix of . ( denotes the sequence of letters consisting of the first elements of the primitive .)
In other words, if a sequence is represented by the pair then the sequence is a prefix of a primitive in iff , and in this case is a prefix of and is represented by the pair . A procedure computes the transition table and builds the array as well. is true iff the sequence represented by is equal to a primitive in .
We can easily implement the algorithm using the arrays and .
Comments