Pagini recente » Cod sursa (job #1287530) | Cod sursa (job #1990845) | Cod sursa (job #282450) | Cod sursa (job #1589675) | Cod sursa (job #863987)
Cod sursa(job #863987)
PROGRAM SECV; {INFOARENA} {OK!}
CONST NMAX=5000; {Complexitatea de ordinul: O(n*log2(n))}
TYPE VECTOR=ARRAY[1..NMAX] OF LONGINT;
{----------------------------------------------------------}
FUNCTION PozPrimul(VAR V:VECTOR; ST,DR:INTEGER):INTEGER;
(*
Pune primul element, V[st], pe pozitia corecta in portiunea din
vectorul V cuprinsa intre indicii [st,dr], mutand elementele mai mici
in stanga sa, iar elementele mai mari in dreapta. Returneaza pozitia
pe care va fi pus primul element.
*)
VAR AUX:LONGINT;
BEGIN
AUX:=V[ST];
WHILE (ST<DR) DO
BEGIN
WHILE (ST<DR)AND(V[DR]>=AUX) DO DR:=DR-1;
V[ST]:=V[DR];
WHILE (ST<DR)AND(V[ST]<=AUX) DO ST:=ST+1;
V[DR]:=V[ST];
END;
V[ST]:=AUX;
PozPrimul:=ST;
END;
{----------------------------------------------------------}
PROCEDURE QUICKSORT(VAR V:VECTOR; ST,DR:INTEGER);
{Complexitatea de ordinul: O(n*log2(n)); sortare foarte eficienta!}
VAR P:INTEGER;
BEGIN
IF (ST<DR) THEN BEGIN
P:=PozPrimul(V,ST,DR);
QUICKSORT(V,ST,P-1); {Divide-Et-Impera}
QUICKSORT(V,P+1,DR);
END;
END;
{----------------------------------------------------------}
FUNCTION CAUTA(X:LONGINT; VAR V:VECTOR; N:INTEGER):INTEGER;
(*
"Cautare binara" (iterativa) a valorii X in vectorul ordonat
strict crescator, V, cu N elemente distincte. Valoarea X se afla
in vectorul V! Functia returneaza pozitia elementului X in sir.
Complexitatea cautarii: O(log2(n)).
*)
VAR ST,DR,MIJ:INTEGER;
BEGIN
ST:=1;
DR:=N;
WHILE (ST<DR) DO BEGIN
MIJ:=(ST+DR) DIV 2;
IF (X>V[MIJ]) THEN ST:=MIJ+1
ELSE DR:=MIJ;
END;
CAUTA:=ST;
END;
{----------------------------------------------------------}
VAR V,V1,V2:VECTOR;
START:ARRAY[1..NMAX] OF 0..NMAX;
N,N2,I,P,L,LMIN:INTEGER;
MIN,MAX:LONGINT;
F,G:TEXT;
BEGIN
ASSIGN(F,'secv.in');
RESET(F);
ASSIGN(G,'secv.out');
REWRITE(G);
READLN(F,N);
FOR I:=1 TO N DO READ(F,V[I]);
V1:=V;
QUICKSORT(V1,1,N); {V1= sirul V ordonat crescator}
{Pun in sirul V2 valori distincte din V1, in ordine strict crescatoare!}
N2:=1; {N2= card(V2)}
V2[1]:=V1[1];
FOR I:=2 TO N DO
IF (V1[I]<>V1[I-1]) THEN BEGIN
N2:=N2+1;
V2[N2]:=V1[I];
START[N2]:=0;
END;
(*
OBS.: START[I]= pozitia din sirul V de unde incepe cea mai "apropiata"
subsecventa ce contine un subsir strict crescator ce
incepe cu valoarea minima din sirul V si se termina
cu valoarea curenta, V2[I]; I=1..N2.
Altfel, are valoarea zero!
*)
MIN:=V1[1];
MAX:=V1[N];
LMIN:=N+1;
{=== PROGRAMARE DINAMICA ===}
FOR I:=1 TO N DO
BEGIN
IF (V[I]=MIN) THEN START[1]:=I; {#1: Incepe o noua subsecventa!}
IF (V[I]>MIN) THEN BEGIN {#2: Se extinde subsecventa curenta!}
P:=CAUTA(V[I],V2,N2);
START[P]:=START[P-1];
END;
IF (V[I]=MAX)AND(START[N2]>0) THEN
BEGIN {#3: Se incheie subsecventa curenta!}
L:=I-START[N2]+1;
IF (L<LMIN) THEN LMIN:=L;
END;
END;
IF (LMIN<N+1) THEN WRITE(G,LMIN)
ELSE WRITE(G,-1);
CLOSE(F);
CLOSE(G);
END.