Cod sursa(job #45510)

Utilizator astronomyAirinei Adrian astronomy Data 1 aprilie 2007 16:53:42
Problema Elimin 2 Scor 90
Compilator c Status done
Runda Arhiva de probleme Marime 2.3 kb
#include <stdio.h>
#include <string.h>

#define MAXN 2048

int N, M, K, L, LG, B[MAXN], sol[MAXN], prev[MAXN][10];
short int A[MAXN][MAXN];

void solve(void)
{
    int i, j, k, t = 0, s, e, p, cmax, poz;

    A[N][N] = 1;

    for(j = 0; j <= 9; j++)
     for(i = 1; i <= N; i++)
      if(B[i] == j)
        prev[i][j] = i;
      else
        prev[i][j] = prev[i-1][j];
        
    for(i = N-1; i >= 1; i--)
     for(A[i][i] = 1, j = i+1; j <= N; j++)
     {
        A[i][j] = A[i+1][j];
        if(prev[j][ B[i] ] > i)
        {
            k = prev[j][B[i]];
            if(A[i+1][k-1]+2 > A[i][j])
                A[i][j] = A[i+1][k-1]+2;
        }
     }

    L = 1, s = 1, e = N;
    for(i = 1; i <= N; i++)
     if(B[i] > 0)
     {
        p = prev[N][B[i]];
        if(p > i && 2+A[i+1][p-1] > L)
            L = 2+A[i+1][p-1], s = i, e = p;
     }

    LG = L, i = s, j = e;

    while(L)
    {
        if(L == 1)
        {
            for(cmax = -1, k = i; k <= j; k++)
             if(B[k] > cmax)
                cmax = B[k];
            sol[++K] = cmax;
            L--;
        }
        else
        {
            for(cmax = -1, k = i; k <= j; k++)
             if(B[k] > cmax && A[k][j] == L)
             {
                p = prev[j][B[k]];
                if(p > k && A[k+1][p-1] == L-2)
                    poz = k, cmax = B[k];
             }
            sol[++K] = cmax, i = poz+1, j = prev[j][B[poz]]-1;
            L -= 2;
        }
    }
}

void read_data(void)
{
    int i, j, k;
    char sir[3000];
    
    scanf("%s\n", &sir), N = strlen(sir);

    for(i = 1; i <= N; i++)
        B[i] = sir[i-1]-'0';
}

void write_data(void)
{
    int i, j;

    if(LG & 1) // lungime impara
    {
        for(j = 1; j <= K; j++)
            printf("%d", sol[j]);
        for(j = K-1; j >= 1; j--)
            printf("%d", sol[j]);
        printf("\n");
    }
    else // lungime para
    {
        for(j = 1; j <= K; j++)
            printf("%d", sol[j]);
        for(j = K; j >= 1; j--)
            printf("%d", sol[j]);
        printf("\n");
    }
}

int main(void)
{
    freopen("elimin2.in", "rt", stdin);
    freopen("elimin2.out", "wt", stdout);

    read_data();
    solve();
    write_data();

    return 0;
}