Cod sursa(job #1599106)

Utilizator Master011Dragos Martac Master011 Data 13 februarie 2016 16:47:10
Problema ADN Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.9 kb
#include<cstdio>
#include<cstring>
using namespace std;

FILE *in, *out;
const int nMax = 19, sMax = 30050;
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];
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]] = '@';
    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] = z[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;
}

void recSir(int nod, int mask){

    int newNod = pred[mask][nod], inc = 0;
    if(newNod > -1){
        recSir(newNod, mask ^ (1 << nod));
        inc = cost[newNod][nod];
    }

    fputs(s[nod] + inc, out);
}

int main(){
    in = fopen("adn.in","r");
    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){
            pred[i][j] = -1;
            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;
        }
    }
    recSir(nodC, (1 << n) - 1);
    fprintf(out,"\n");
    return 0;
}