Cod sursa(job #1470862)

Utilizator stoianmihailStoian Mihail stoianmihail Data 12 august 2015 15:15:01
Problema Subsir crescator maximal Scor 100
Compilator c Status done
Runda Arhiva educationala Marime 2.35 kb
#include <stdio.h>

#define Nadejde 100001

/**  Algoritm problema "Scmax":
 *   Psihologia concursurilor de informatica:
 *  "Fie "a" vectorul citit. Se parcurge vectorul de la stanga la dreapta
 * si se construiesc in paralel doi vectori: "set" si "sorted".
 *   Se ia fiecare element din "a" si se suprascrie peste cel mai mic element
 * din "sorted" care este strict mai mare decat el. Evident, daca nu exista
 * un asemenea element in "sorted", elementul din "a" se pune la finalul vectorului
 * "sorted". Concomitent, se noteaza in vectorul "set", pozitia pe care a fost
 * adaugat.
 *   La final, se parcurge de la dreapta la stanga vectorul "set", construindu-se
 * astfel subsirul strict crescator maximal.
 *   Multumim Doamne!
**/

int N;
int M = 1;
int a[Nadejde];      /// vectorul de la intrare.
int set[Nadejde];    /// pozitiile in "sorted".
int scmax[Nadejde];  /// solutia noastra.
int sorted[Nadejde]; /// sorted[i] este valoarea minima in care se poate termina un sir crescator de lungime "i".

/** Cauta cel mai mic numar mai mare strict decat "x". **/
int bSearch(int lo, int hi, int x) {
  if (x <= sorted[lo]) {
    return lo;
  }
  while (hi - lo > 1) {
    int mid = (lo + hi) >> 1;
    if (sorted[mid] < x) {
      lo = mid;
    } else {
      hi = mid;
    }
  }
  return hi;
}

int main(void) {
  int i, pos, len = 1;
  FILE *f = fopen("scmax.in", "r");

  /** Daca a[i] este mai mare decat toate numerele din "sorted",
   * il punem la final, iar daca nu, il asezam pe pozitia "pos". **/
  fscanf(f, "%d", &N);
  for (i = 1; i <= N; i++) {
    fscanf(f, "%d", &a[i]);
    set[i] = pos = bSearch(1, M, a[i]);
    if (pos == M) {
      sorted[M++] = a[i];
    } else {
      sorted[pos] = a[i];
    }
  }
  fclose(f);

  /** Parcurge de la dreapta la stanga "set" si gaseste
   * subsirul strict crescator. **/
  M--;
  for (i = N; i > 0; i--) {
    if (set[i] == M) {
      M--;
      /** Trebuie sa fie neaparat strict crescator! **/
      if (a[i] != scmax[len - 1]) {
        scmax[len++] = a[i];
      }
    }
  }

  f = fopen("scmax.out", "w");

  /** Afiseaza subsirul obtinut. **/
  fprintf(f, "%d\n", len - 1);
  for (i = len - 1; i > 0; i--) {
    fprintf(f, "%d ", scmax[i]);
  }
  fputc('\n', f);
  fclose(f);

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