Cod sursa(job #357009)

Utilizator katakunaCazacu Alexandru katakuna Data 17 octombrie 2009 19:15:05
Problema ADN Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.05 kb
#include <cstdio>
#include <string.h>

#define Nmax 20
#define Lmax 31000

int n, i, j, ok, l, cst, j2;
int len[Nmax], P[Lmax], viz[Nmax], viz2[Nmax], C[Nmax][Nmax], A[Nmax][ 1 << (Nmax-2) + 1], T[Nmax][1 << (Nmax-2) + 1], Max, Pmax;
char s[Nmax][Lmax];


void prefix (int a) {
	
	int i, k = 0;
	for ( i = 2; i <= len[a]; i++) {
		while (k && s[a][k+1] != s[a][i])
			k = P[k];
		
		if (s[a][k+1] == s[a][i])
			P[i] = ++k;
		else
			P[i] = 0;
	}
	
}

void potrivire (int a, int b) {
	
	int i, k = 0;
	for (i = 1; i <= len[b]; i++) {
		while (k && s[a][k+1] != s[b][i]) 
			k = P[k];
		
		if (s[a][k+1] == s[b][i]) {
			k++;
			if (k == len[a]) {
				viz[a] = 1; return ;
			}
		}
		
	}	
	
	C[b][a] = k;
}

int main () {

	FILE *f = fopen ("adn.in", "r");
	FILE *g = fopen ("adn.out", "w");

	fscanf (f, "%d", &n);
	for (i = 0; i < n; i++) {
		s[i][0] = ' ';
		fscanf (f, "%s", s[i] + 1);
		len[i] = strlen (s[i]) - 1;
	}
	
	for (i = 0; i < n; i++) {
		prefix (i);
		for (j = 0; j < n; j++)
			if (i != j) 
				potrivire (i, j);
	}
	
	int N = (1 << n) - 1;
	for (j = 1; j <= N; j++) {
		ok = 1;
		for (i = 0; i < n; i++) {
			if ( ((j >> i)&1) ) {
				if (viz[i]){ ok = 0; break; }
				viz2[i] = 1;
			}
			else viz2[i] = 0;
		}
		
		if (ok)
			for (i = 0; i < n; i++) {
				A[i][j] = -1;
				if (!viz[i] && !viz2[i] )
					for (l = 0; l <= n; l++) 
						if ( ((j >> l)&1) ) {
							j2 = j;	j2^= (1 << l);
							cst = C[i][l] + A[l][j2];
							if ( A[i][j] < cst ) {
								A[i][j] = cst;
								T[i][j] = l;
							}
						}
			}
	}
	
	Max = -1; 
	j = (1 << n); j--;
	for (i = 0; i < n; i++)
		if (viz[i])
			j^= (1 << i);
	
	for (i = 0; i < n; i++)
		if (!viz[i]) {
			j2 = j ^ (1 << i);
			if (Max < A[i][j2]) {
				Max = A[i][j2];
				Pmax = i;
			}
		}
	
	int p2 = -1, u;
	while (j) {
		if (p2 == -1) u = 0;
		else u = C[p2][Pmax];
		fprintf (g, "%s", s[Pmax]+1+u);
		j^= (1 << Pmax);
		p2 = Pmax;
		Pmax = T[Pmax][j];
	}
	
	fclose (f);
	fclose (g);

	return 0;

}