Cod sursa(job #1598393)

Utilizator Master011Dragos Martac Master011 Data 12 februarie 2016 21:14:42
Problema ADN Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.94 kb
#include<cstdio>
#include<cstring>
using namespace std;

const int nMax = 19, sMax = 30010;
int n;
char s[nMax][sMax], f[sMax * 2];
int z[sMax * 2], lung[nMax], cost[nMax][nMax], din[1<<nMax][nMax], pred[1<<nMax][nMax], sol[nMax];
bool e[nMax];

int zFunction(int x, int y, int type){

    for(int i = 0 ; i < lung[y] ; ++i) f[i] = s[y][i];
    f[lung[y]] = '0';
    for(int i = 0 ; i < lung[x] ; ++i) f[i + lung[y] + 1] = s[x][i];


    int l = lung[x] + lung[y] + 1, L, R, k, co = 0, co2 = 0;
    L = R = 0;
    for(int i = 0 ; i < l ; ++i){
        if(i > R){
            L = R = i;
            while(R < l && f[R] == f[R-L]) R++;
            z[i] = R - L, R--;
        }else{
            k = i - L;
            if(z[k] > R - i){
                L = i;
                while(R < l && f[R] == f[R-L]) R++;
                z[i] = R - L, R--;
            }else{
                z[i] = k;
            }
        }
        if(i > lung[y] && z[i] == l - i && z[i] > co) co = z[i];
        if(i > lung[y] && z[i] >= lung[y]) co2 = 1;
    }
    if(type) return co;
    return co2;
}

int main(){
    FILE *in = fopen("adn.in","r");
    FILE *out = fopen("adn.out","w");

    fscanf(in,"%d\n", &n);
    for(int i = 0 ; i < n ; ++i){
        fgets(s[i], sMax, in);
        lung[i] = strlen(s[i]) - 1;
    }

    for(int i = 0 ; i < n ; ++i){
        for(int j = 0 ; j < n ; ++j){
            if(i != j && lung[i] <= lung[j] && !e[i] && !e[j]){
                if(zFunction(j, i, 0))
                    e[i] = true;
            }
        }
    }
    int cnt = 0;
    for(int i = 0; i < n ; ++i){
        if(!e[i]){
            for(int k = 0 ; k < lung[i] ; ++k)
                s[cnt][k] = s[i][k];
            s[cnt][lung[i]] = 0;
            lung[cnt] = lung[i];
            ++cnt;
        }
    }
    n = cnt;

    for(int i = 0 ; i < n ; ++i)
        for(int j = 0 ; j < n ; ++j)
            if(i != j)
                cost[i][j] = zFunction(i, j, 1);

    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(j != k && i & (1 << k))
                        if(din[i][j] < din[i ^ (1 << j)][k] + cost[k][j]){
                            din[i][j] = din[i ^ (1 << j)][k] + cost[k][j];
                            pred[i][j] = k;
                        }
    int co = 0, nodC = 0;
    for(int i = 0 ; i < n ; ++i){
        if(din[(1 << n) - 1][i] >= co){
            co = din[(1 << n) - 1][i];
            nodC = i;
        }
    }

    cnt = 0;
    int i = (1 << n) - 1, t;
    while(cnt < n){
        sol[cnt++] = nodC;
        t = nodC;
        nodC = pred[i][nodC];
        i ^= (1 << t);
    }

    int inc = 0;
    for(int i = cnt - 1 ; i >= 0 ; --i){
        fputs(s[sol[i]] + inc, out);
        if(i > 0) inc = cost[sol[i]][sol[i - 1]];
    }
    fprintf(out,"\n");
    return 0;
}