Cod sursa(job #1508676)

Utilizator hrazvanHarsan Razvan hrazvan Data 22 octombrie 2015 20:42:01
Problema Elimin 2 Scor 100
Compilator c Status done
Runda Arhiva de probleme Marime 2.39 kb
#include <stdio.h>
#define MAXL 2002
#define SIGMA 10
char s[MAXL + 2];
short d[MAXL][MAXL], pr[MAXL][SIGMA], ult[MAXL][SIGMA];
int dr;
char rez[MAXL];

inline void precalc(int n){
  int p, i, k;
  for(k = 0; k < SIGMA; k++){
    p = -1;
    for(i = n - 1; i >= 0; i--){
      if(s[i] == k + '0')
        p = i;
      pr[i][k] = p;
    }
    p = -1;
    for(i = 0; i < n; i++){
      if(s[i] == k + '0')
        p = i;
      ult[i][k] = p;
    }
  }
}

short calc(int st, int dr){
  if(st > dr || st == -1 || dr == -1)
    return 0;
  if(st == dr)
    d[st][dr] = 1;
  if(d[st][dr] != 0)
    return d[st][dr];
  int k, max = 0, x;
  for(k = SIGMA - 1; k >= 0; k--){
    if(pr[st][k] >= st && pr[st][k] <= dr){
      x = calc(pr[st][k] + 1, ult[dr][k] - 1);
      if(pr[st][k] == ult[dr][k])
        x++;
      else
        x += 2;
      if(x > max)
        max = x;
    }
  }
  d[st][dr] = max;
  return d[st][dr];
}

int main(){
  FILE *in = fopen("elimin2.in", "r");
  fgets(s, MAXL + 2, in);
  fclose(in);
  int n;
  n = 0;
  while(s[n] >= '0' && s[n] <= '9')
    n++;
  precalc(n);
  calc(0, n - 1);
  int i, j, k, x;
  char g;
  i = 0;  j = n - 1;
  while(i <= j && d[i][j] != 0){
    g = 0;
    for(k = SIGMA - 1; k >= 0 && !g; k--){
      if(!(k == 0 && i == 0 && j == n - 1)){
        if(pr[i][k] <= j && pr[i][k] >= i){
          x = calc(pr[i][k] + 1, ult[j][k] - 1);
          if(pr[i][k] == ult[j][k])
            x++;
          else
            x += 2;
          if(x == d[i][j]){
            rez[dr] = k;
            if(pr[i][k] != ult[j][k])
              rez[dr] += '0';
            dr++;
            i = pr[i][k] + 1;
            j = ult[j][k] - 1;
            g = 1;
          }
        }
      }
    }
    if(g == 0){
      d[i][j] = 0;
      for(k = SIGMA - 1; k > 0 && !g; k--){
        if(pr[i][k] <= j && pr[i][k] >= i){
          x = calc(pr[i][k] + 1, ult[j][k] - 1);
          if(pr[i][k] == ult[j][k])
            x++;
          else
            x += 2;
          if(x > d[i][j])
            d[i][j] = x;
        }
      }
    }
  }
  FILE *out = fopen("elimin2.out", "w");
  for(i = 0; i < dr; i++){
    if(rez[i] < '0')
      fputc(rez[i] + '0', out);
    else
      fputc(rez[i], out);
  }
  for(i = dr - 1; i >= 0; i--){
    if(rez[i] >= '0')
      fputc(rez[i], out);
  }
  fclose(out);
  return 0;
}