Cod sursa(job #863987)

Utilizator mariusbuzgariuBuzgariu Marius mariusbuzgariu Data 24 ianuarie 2013 15:33:59
Problema Secv Scor 100
Compilator fpc Status done
Runda Arhiva de probleme Marime 3.44 kb
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.