Cod sursa(job #654727)

Utilizator balazstxBalazs Tibor balazstx Data 30 decembrie 2011 20:41:51
Problema ADN Scor 100
Compilator c Status done
Runda Arhiva de probleme Marime 2.54 kb
/* 
 * File:   and.c
 * Author: Rendszergazda
 *
 * Created on 2011. december 30., 17:39
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int drb;
char c[19][30002];
int matcheu[19][19];
int len[19];
int inactiv = 0;
int oszhosz[19][1 << 19];
short elozo[19][1 << 19];
const int infin = 3000100;

void kiir(int k, int min) {
    if (!min) return;
    kiir(k & (~(1 << min - 1)), elozo[min][k]);
    printf("%s", c[min]+1+matcheu[elozo[min][k]][min]);
}

int main(int argc, char** argv) {
    freopen("adn.in", "r", stdin);
    freopen("adn.out", "w", stdout);

    scanf("%d", &drb);
    int i;
    for (i = 1; i <= drb; i++) {
        scanf("%s\n", c[i] + 1);
        len[i] = strlen(c[i] + 1);
    }
    int j, x;
    int eloz[30002];
    eloz[0] = 0;
    eloz[1] = 0;
    for (i = 1; i <= drb; i++) {

        for (j = 2, x = 0; j <= len[i]; j++) {
            while (x && c[i][j] != c[i][x + 1]) x = eloz[x];
            if (c[i][j] == c[i][x + 1])x++;
            eloz[j] = x;
        }
/*
        printf("\n");
        printf("%s\n", c[i] + 1);
*/
/*
        for (j = 0; j <= len[i]; j++) {
            printf("%d ", eloz[j]);
        }
*/

        for (j = 1; j <= drb; j++) {
            if (i == j || inactiv & 1 << (j - 1)) continue;
            int y;
            for (y = 0, x = 0; y <= len[j]; y++) {
                while (x && c[j][y] != c[i][x + 1]) x = eloz[x];
                if (c[j][y] == c[i][x + 1]) x++;
                if (x == len[i]) {
                    inactiv |= 1 << (i - 1);
                    x = 0;
                    break;
                }
            }
            matcheu[j][i] = x;
        }
    }

    for (i = 0; i < 19; i++)
        for (j = 0; j < 1 << 19; j++)
            oszhosz[i][j] = infin;

    oszhosz[0][inactiv] = 0;
    int k = (1 << drb) - 1;

    for (i = inactiv; i <= k; i++)
        for (j = 0; j <= drb; j++)
            if (oszhosz[j][i] != infin)
                for (x = 1; x <= drb; x++)
                    if (!(i & (1 << (x - 1))) &&
                            oszhosz[j][i] - matcheu[j][x] < oszhosz[x][i | (1 << (x - 1))]) {
                        oszhosz[x][i | (1 << (x - 1))] = oszhosz[j][i] - matcheu[j][x];
                        elozo[x][i | (1 << (x - 1))] = j;
                    }


    int min = 0;
    for (i = 1; i <= drb; i++)
        if (oszhosz[i][k] < oszhosz[min][k]) min = i;    
    kiir(k, min);


/*
    for (i = 0; i <= drb; i++) {
        printf("\n");
        for (j = 0; j <= k; j++) {
            printf("%d ", oszhosz[i][j]);
        }
    }
*/


    return (EXIT_SUCCESS);
}