Cod sursa(job #1569747)

Utilizator stoianmihailStoian Mihail stoianmihail Data 15 ianuarie 2016 21:30:05
Problema Secv Scor 100
Compilator c Status done
Runda Arhiva de probleme Marime 2.14 kb
#include <stdio.h>
#include <limits.h>

#define Nadejde 5000
#define NIL -1

typedef struct {
  int v, pos;
} save;

int N, M;
int val[Nadejde + 1];          // sirul normalizat.
int last[Nadejde + 1];         // last[i] = pozitia unde incepe un subsir cu proprietatea data si care se termina in valoarea i.
int seen[Nadejde + 1];         // seen[i] = ultima pozitie pe care se afla valoarea i.
save tmp, sorted[Nadejde + 1]; // sortam sirul nostru.

/** MIN(X, Y). **/
int MIN(int X, int Y) {
  return X < Y ? X : Y;
}

/** Sorteaza "sorted". **/
void sort(int begin, int end) {
  int b = begin, e = end;
  int pivot = sorted[(b + e) >> 1].v;

  while (b <= e) {
    while (sorted[b].v < pivot) {
      b++;
    }
    while (sorted[e].v > pivot) {
      e--;
    }
    if (b <= e) {
      save tmp = sorted[b];
      sorted[b++] = sorted[e];
      sorted[e--] = tmp;
    }
  }
  if (begin < e) {
    sort(begin, e);
  }
  if (b < end) {
    sort(b, end);
  }
}

/** Normalizeaza sirul. **/
void unique() {
  int i, j, pos = 0;

  for (i = 1; i <= N; i = j) {
    pos++, j = i;
    do {
      val[sorted[j++].pos] = pos;
    } while ((j <= N) && (sorted[j].v == sorted[i].v));
  }
  M = pos;
}

int main(void) {
  int i, len = INT_MAX;
  FILE *f = fopen("secv.in", "r");

  /* Citirea datelor. */
  fscanf(f, "%d", &N);
  for (i = 1; i <= N; i++) {
    fscanf(f, "%d", &sorted[i].v);
    sorted[i].pos = i;
    last[i] = NIL;
  }
  fclose(f);

  /* Normalizam datele. */
  sort(1, N);
  unique();

  /* Calcularea solutiei. */
  last[0] = 0;
  for (i = 1; i <= N; i++) {
    /* Daca s-a format un subsir cu proprietatea data pana la valoarea curenta minus 1. */
    if (last[val[i] - 1] != NIL) {
      /* Gasim subsecventa de lungime minima. */
      if ((val[i] == M) && (last[M] != NIL)) {
        len = MIN(len, seen[M] - last[M] + 1);  
      }
      last[val[i]] = ((val[i] == 1) ? i : last[val[i] - 1]);
      seen[val[i]] = i;
    }
  }

  /* Afisarea solutiei. */
  freopen("secv.out", "w", stdout);
  fprintf(stdout, "%d\n", ((len == INT_MAX) ? ((last[M] == NIL) ? NIL : seen[M] - last[M] + 1) : len));
  fclose(stdout);

  /// Multumim Doamne!
  puts("Doamne ajuta!");
  return 0;
}