Cod sursa(job #315995)

Utilizator Mishu91Andrei Misarca Mishu91 Data 17 mai 2009 22:24:05
Problema ADN Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.22 kb
#include <cstdio>
#include <cstring>

#define MAX_N 18
#define MAX_L 30001
#define INF 0x3f3f3f3f

int N, Sz[MAX_N], M;
char S[MAX_N][MAX_L];
int C[MAX_N][MAX_N], pi[MAX_N];
int A[1 << MAX_N][MAX_N], T[MAX_N];

struct adn
{
	int x, y;
} Ant[1 << MAX_N][MAX_N];

void citire()
{
	scanf("%d",&N);
	
	for(int i = 0; i < N; ++i)
	{
		scanf(" %s",S[i]+1);
		Sz[i] = strlen(S[i]+1);
	}
}

void make_prefix(char A[MAX_N], int N)
{
	pi[1] = 0;
	for(int i = 2, q = 0; i <= N; ++i)
	{
		while(q && A[q+1] != A[i])
			q = pi[q];
		
		if(A[q+1] == A[i])
			++q;
		
		pi[i] = q;
	}
}

int search(char A[MAX_N], int N, char B[MAX_N], int M)
{
	make_prefix(A, N);
	
	for(int i = 1, q = 0; i <= M; ++i)
	{
		while(q && A[q+1] != B[i])
			q = pi[q];
		
		if(A[q+1] == B[i])
			++q;
		
		if(i == M)
			return q;
		
		if(q == N)
			return -1;
	}
	return 0;
}

void pre()
{
	for(int i = 0; i < N; ++i)
		for(int j = i; j < N; ++j)
		{
			C[i][j] = search(S[j], Sz[j], S[i], Sz[i]);
			C[j][i] = search(S[i], Sz[i], S[j], Sz[j]);
		}
}

void solve()
{
	M = 1 << N;
	
	for(int i = 0; i < M; ++i)
		for(int j = 0; j < N; ++j)
			A[i][j] = INF;
	
	for(int i = 0; i < N; ++i)
		A[(1 << i)][i] = Sz[i];
		
	for(int i = 1; i < M; ++i)
		for(int j = 0; j < N; ++j)
		{
			if(A[i][j] == INF) continue;
			
			for(int k = 0; k < N; ++k)
			{
				if(i & (1 << k)) continue;
				if(j == k) continue;
				int _i = i + (1 << k);
				if(C[j][k] == -1)
				{
					if(A[_i][j] > A[i][j])
					{
						A[_i][j] = A[i][j];
						Ant[_i][j].x = i;
						Ant[_i][j].y = j;
					}
				}
					
				else
					if(A[_i][k] > A[i][j] + Sz[k] - C[j][k])
					{
						A[_i][k] = A[i][j] + Sz[k] - C[j][k];
						Ant[_i][k].x = i;
						Ant[_i][k].y = j;
					}
			}
		}
}

void reconst()
{
	int x = M-1, y = 0, Sol = A[M-1][0], nr = N;
	
	for(int i = 1; i < N; ++i)
		if(Sol > A[M-1][i])
			Sol = A[M-1][i],
			y = i;
	
	while(x)
	{
		T[--nr] = y;
		int auxx = Ant[x][y].x, auxy = Ant[x][y].y;
		x = auxx;
		y = auxy;
	}

	for(int i = 1; i <= Sz[T[0]]; ++i)
		printf("%c",S[T[0]][i]);
	for(int i = 1; i < N; ++i)
		for(int j = C[T[i-1]][T[i]]+1; j <= Sz[T[i]]; ++j)
			printf("%c", S[T[i]][j]);
}

int main()
{
	freopen("adn.in","rt",stdin);
	freopen("adn.out","wt",stdout);
	
	citire();
	pre();
	solve();
	reconst();
}