Cod sursa(job #174610)

Utilizator vlad.maneaVlad Manea vlad.manea Data 9 aprilie 2008 00:30:43
Problema Elimin 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.93 kb
#include <stdio.h>
#include <string.h>
#define nmax 2048

short N, nm, L[10][nmax], R[10][nmax], P[nmax][nmax], sol[nmax], A[nmax];

char S[nmax];

void build(int i, int j, int start)
{
  if (i > j) return;

  int l, r, c, k, m = 0;

  if (start == 1)
  {
    for (c = 9; c; c--)
    {
      l = L[c][i];
      r = R[c][j];

      if (P[l][r] > m)
      {
        m = P[l][r];
        k = c;
      }
    }

    printf("%d", k);
    build(L[k][i]+1, R[k][j]-1, 0);
    if (m > 1) printf("%d", k);
  }
  else
  {
    for (c = 9; c >= start; c--)
    {
      l = L[c][i];
      r = R[c][j];

      if (P[l][r] > m)
      {
        m = P[l][r];
        k = c;
      }
    }

    printf("%d", k);
    build(L[k][i]+1, R[k][j]-1, 0);
    if (m > 1) printf("%d", k);
  }
}

void read()
{
  int i;

  freopen("elimin2.in", "r", stdin);

  freopen("elimin2.out", "w", stdout);

  scanf("%s", &S);

  for (i = 0, N = strlen(S); i < N; ++i)
    A[i+1] = S[i] - '0';
}

void solve()
{
  int i, lg, c, imax, j;

  // P[i][j] = lungimea maxima a unui palindrom care porneste din i, j
  for (i = 1; i <= N; ++i)
    P[i][i] = 1;

  for (lg = 2; lg <= N; ++lg)
    for (i = 1, imax = N-lg+1; i <= imax; ++i)
    {
      j = i+lg-1;
      P[i][j] = P[i+1][j] > P[i][j-1]? P[i+1][j]: P[i][j-1];
      if (i < j && A[i] == A[j] && 2 + P[i+1][j-1] > P[i][j])
        P[i][j] = 2 + P[i+1][j-1];
    }

  // L[c][i] = pozitia pe care se afla prima cifra c de la pozitia i inainte
  for (i = N; i; i--)
    for (c = 0; c < 10; ++c)
      L[c][i] = (A[i] == c ? i: L[c][i+1]);

  // R[c][i] = pozitia pe care se afla ultima cifra c de la pozitia j inapoi
  for (i = 1; i <= N; ++i)
    for (c = 0; c < 10; ++c)
      R[c][i] = (A[i] == c? i: R[c][i-1]);

  build(1, N, 1);
}

void write()
{
  int i;

  printf("\n");
}

int main()
{
  read();

  solve();

  write();

  return 0;
}