Cod sursa(job #693663)

Utilizator psycho21rAbabab psycho21r Data 27 februarie 2012 15:13:40
Problema ADN Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.94 kb
#include <fstream>
#include <string>
#define INF 0x3f3f3f3f
using namespace std;
int pi[30005], graph[18][18], st, C[(1 << 18)][18], before[(1 << 18)][18];
bool not_show[18];
string adn[18];
bool not_included(int i, int j)
{
    if(adn[i].size() > adn[j].size())
        return true;
    int j_pos = 0, i_pos = 0;
    while(j_pos+i_pos < adn[i].size())
    {
        if(adn[i][i_pos] == adn[j][j_pos+i_pos])
        {
            if(i_pos == adn[i].size()-1)
            {
                not_show[i] = true;
                return false;
            }
            else
                ++i_pos;
        }
        else
        {
            j_pos = j_pos + i_pos - pi[i_pos];
            if(pi[i]>-1)
                i = pi[i];
            else
                i = 0;
        }
    }
    return true;
}
int main()
{
    int n;
    ifstream in("adn.in");
    in >> n;
    for(int i = 0; i < n; ++i) in >> adn[i];
    in.close();
    for(int i = 0; i < n; ++i)  //Pi function
    {
        int w_size = adn[i].size();
        int back = 0, pos = w_size-3;
        pi[w_size-1] = -1;
        pi[w_size-2] = 0;

        while (pos >= 0)
        {
            if(adn[i][pos+1] == adn[i][w_size-back-1])
            {
                ++back;
                pi[pos] = back;
                --pos;
            }
            else
            if(back > 0)
                back = pi[w_size-back-1];
            else
            {
                pi[pos] = 0;
                --pos;
            }
        }
        for(int j = 0; j < n; ++j) //Make graph
        {
            if(i!=j&&(!not_show[i]))
            {
                int now = 0, pos = 0, w_size = adn[i].size(), s_size = adn[j].size();
                while (now < s_size)
                {
                    if(((adn[i][w_size-1-pos] == adn[j][s_size-1-(now+pos)])&&(now+pos < s_size))||(now+pos >= s_size))
                    {
                        if(pos == w_size-1)
                        {
                            if(now+pos < s_size)
                            {
                                not_show[i] = true;
                                break;
                            }
                            graph[i][j] = s_size - now;
                            break;
                        }
                        else
                            ++pos;
                    }
                    else
                    {
                        now = now + pos - pi[w_size-1-pos];
                        if(pi[w_size-1-pos] > -1)
                            pos = pi[w_size-1-pos];
                        else
                            pos = 0;
                    }
                }
            }
        }
    }
    for(int i = 0; i < (1<<n); ++i)
        for(int j = 0; j < n; ++j)
            C[i][j] = INF;
    for(int i = 0; i < n; ++i)
        C[1<<i][i] = 0;
    for(int i = 1; i < (1<<n); ++i)
    {
        for(int j = 0; j < n; ++j)
        {
            if(i&(1<<j))
                for(int k = 0; k < n; ++k)
                {
                    if((C[i][j] == INF && C[i^(1<<j)][k] != INF) || (C[i^(1<<j)][k] != INF && C[i^(1<<j)][k] + graph[j][k] > C[i][j]))
                    {
                        C[i][j] = C[i^(1<<j)][k] + graph[k][j];
                        before[i][j] = k;
                    }
                }
        }
    }
    int i = (1<<n)-1, max = -1, sj = 0, prev = -1, tmp;
    for(int j = 0; j < n; ++j)
        if(C[i][j] > max && C[i][j] != INF)
        {
            max = C[i][j];
            sj = j;
        }
    ofstream out("adn.out");
    for(int j = 0; j < n; ++j)
    {
        if(!not_show[sj])
        {
            for(int k = graph[prev][sj]; k < adn[sj].size(); ++k)
                out << adn[sj][k];
        }
        tmp = sj;
        sj = before[i][tmp];
        i = i ^ (1<<tmp);
        prev = tmp;
    }
    out.close();
    return 0;
}