Cod sursa(job #973958)

Utilizator claudiumihailClaudiu Mihail claudiumihail Data 16 iulie 2013 08:15:10
Problema Elimin 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.91 kb
#include <fstream>
#include <iostream>
#include <string>
#include <iterator>
#include <algorithm>
#include <cstring>

#define MAXN 2048

using namespace std;

char number[MAXN];
char palindrom[MAXN];

short mat[MAXN][MAXN];
short L[10][MAXN];
short R[10][MAXN];

int main()
{
    fstream fin("elimin2.in", fstream::in);
    fstream fout("elimin2.out", fstream::out);
    
    fin >> number + 1;
    //cout << number + 1 << endl << endl;
    
    int len = strlen(number + 1);
    
    for (int i=1; i<=len; ++i)
    {
        mat[i][i] = 1;
    }
    
    for (int l=1; l<len; ++l)
    {
        for (int i=1; i<=len - l; ++i)
        {
            int j = i + l;
            if (number[i] == number[j])
            {
                mat[i][j] = 2 + mat[i+1][j-1];
            }
            else
            {
                mat[i][j] = max(mat[i+1][j], mat[i][j-1]);
            }
        }
    }
    
    ostream_iterator<int> itOut(cout, " ");
    
    for (char c = '0'; c <= '9'; ++c)
    {
        int prevPos = 0;
        for (int i=1; i<=len; ++i)
        {
            if (number[i] == c)
            {
                prevPos = i;
            }
            R[c - '0'][i] = prevPos;
        }

        //copy_n(R[c - '0'] + 1, len, itOut);
        //cout << endl;
    }
    //cout << endl;
    
    for (char c = '0'; c <= '9'; ++c)
    {
        int prevPos = len + 1;
        for (int i=len; i>=1; --i)
        {
            if (number[i] == c)
            {
                prevPos = i;
            }
            L[c - '0'][i] = prevPos;
        }

        //copy_n(L[c - '0'] + 1, len, itOut);
        //cout << endl;
    }
    //cout << endl;

    /*for (int i=1; i<=len; ++i)
    {
        for (int j=1; j<=len; ++j)
        {
            cout << mat[i][j] << " ";
        }
        cout << endl;
    }*/
    
    int startDigit = 1;
    int maxLen = 0;
    int left = 1;
    int right = len;
    int index = 0;
    for (; left <= right;)
    {
        int bestL = len;
        int bestR = 0;
        int bestLen = 0;

        for (int c=startDigit; c<=9; ++c)
        {
            int l = L[c][left];
            int r = R[c][right];
            
            //cout << l << " " << r <<  " -- " << mat[l][r] << endl;

            if (l <= r && mat[l+1][r-1] + 1 + (l<r) >= bestLen)
            {
                bestL = l;
                bestR = r;
                bestLen = mat[l+1][r-1] + 1 + (l<r);
            }
        }
        
        if (startDigit != 0)
        {
            maxLen = bestLen;
        }
        
        palindrom[index] = palindrom[maxLen - index - 1] = number[bestR];

        left = L[number[bestR] - '0'][left] + 1;
        right = R[number[bestR] - '0'][right] - 1;

        startDigit = 0;
        index++;
    }
    //cout << endl;
    
    fout << palindrom << "\n";

    return 0;
}