Cod sursa(job #356623)

Utilizator marinMari n marin Data 15 octombrie 2009 17:22:16
Problema ADN Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.37 kb
#include <stdio.h>
#include <string.h>
#define DIM 30010
#define INF 2000000009

char *A[20];
int V[20];
int D[20];

int P[20][DIM];
int T[20][DIM];
int i, N, j, ii, jj, t, k, dn, max, maxim, x, c, d, pMaxim, b, a, last, pMax;

int C[20][20];

int X[20][1<<19];


int main(){
	FILE *f = fopen("adn.in","r");
	fscanf(f,"%d",&N);
	for (i=1;i<=N;i++) {
		A[i] = new char[DIM];
		fscanf(f,"%s",A[i]);
		
		for (j = (D[i] = strlen(A[i]))+1; j>0; j--)
			A[i][j] = A[i][j-1];
	}
	fclose(f);

	for (ii=1;ii<=N;ii++) {
		P[ii][1] = 0;
		for (i=2, k=0;i<=D[ii];i++) {
			while (A[ii][i] != A[ii][k+1] && k>0)
				k = P[ii][k];
			if (A[ii][i] == A[ii][k+1]) {
				k++;
				P[ii][i] = k;
			}
		}
	}
	
	for (ii=1;ii<=N;ii++)
		for (jj=1;jj<=N;jj++) 
			if (ii!=jj){
			
				for (i=1,k=0;i<=D[jj];i++) {
					while (k && A[jj][i]!=A[ii][k+1])
						k = P[ii][k];
					if (A[jj][i] == A[ii][k+1]) {
						k++;
						if (k == D[ii]) {
							V[ii] = 1;
						}
					}
				}
			}
				
	j = 0;
	for (i=1;i<=N;i++) {
		if (V[i] == 0) {
			j++;
			for (t=1;t<=D[i];t++)
				P[j][t] = P[i][t];
			D[j] = D[i];
			A[j] = A[i];
		}
	}
	N = j;
	
	
	for (ii=1;ii<=N;ii++)
		for (jj=1;jj<=N;jj++) 
			if (ii!=jj){
			
				for (i=1,k=0;i<=D[jj];i++) {
					while (k && A[jj][i]!=A[ii][k+1])
						k = P[ii][k];
					if (A[jj][i] == A[ii][k+1]) {
						k++;
						if (k == D[ii]) {
							V[ii] = 1;
						}
					}
				}
				
				C[jj][ii] = k;
			}
	dn = ((1<<(N)) - 1)<<1;
			
	for (i=1;i<=N;i++) {
		for (j=0;j<=dn;j++)
			X[i][j] = -INF;
		X[i][0] = 0;
	}
			
	for (b = 2;b<=dn;b++) {
		for (a = 1; a<=N;a++) {
			max = -INF;
			pMax = 0;
			if (((b >> a)&1) == 0)
				for (i=1;i<=N;i++) 
					if (b & (1<<i)){
						c = b & ~(1<<i);
						c = C[a][i]+X[i][c];
						if (c>max){
							max = c;
							pMax = i;
						}
					}
			T[a][b] = pMax;
			X[a][b] = max;
		}
	}

			
			
	for (i=1;i<=N;i++) {
		x = X[i][dn & ~(1<<i)];
		if (x>maxim) {
			maxim = x;
			pMaxim = i;
		}
	}

	
	FILE *g = fopen("adn.out","w");
	if (N==1) {
		fprintf(g,"%s",A[1]+1);
	} else {
		a = pMaxim;
		b = dn & ~(1<<pMaxim);
		fprintf(g,"%s",A[a]+1);
		last = a;
		while (b) {
			c = T[a][b];
			fprintf(g,"%s",A[c]+C[last][c]+1);
			last = c;
			d = b & ~(1<<c);
			a = c;
			b = d;
		}
	}
	fclose(g);
	
	return 0;
}