Cod sursa(job #492342)

Utilizator hadesgamesTache Alexandru hadesgames Data 14 octombrie 2010 10:13:31
Problema ADN Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.87 kb
#include <cstdio>
#include <vector>

using namespace std;

FILE *in,*out;

char s[19][30050];
int d[20][20];
int a[(1<<18)+5][20];
int pi_aux[30050];
int pi[19][30050];
int pred[(1<<18)+5][20];
const int inf=1<<29;
int size[30];
int gen_pi(int x)
{
	int i,y;
	pi[x][1]=0;
	for (i=2;s[x][i];i++)
	{
		y=pi[x][i-1];
		while (y&&s[x][y+1]!=s[x][i])
			y=pi[x][y];
		if (s[x][y+1]==s[x][i])
			y++;
		pi[x][i]=y;
	}
	return i-1;
}
int search(int x,int y)
{
	int i,z;
	pi_aux[1]=0;
	for (i=2;s[y][i];i++)
	{
		z=pi_aux[i-1];
		while (z&& s[x][z+1]!=s[y][i])
			z=pi[x][z];
		if (s[x][z+1]==s[y][i])
				z++;
		pi_aux[i]=z;
		if (pi_aux[i]==size[x])
			return size[x];
	}
	return pi_aux[i-1];
}
void afis(int i,int j)
{
	if (!i)
		return ;
	afis(i-(1<<(j-1)),pred[i][j]);
	int k;
	for (k=-d[pred[i][j]][j]+1;k<=size[j];k++)
		fprintf(out,"%c",s[j][k]);
}
int main()
{
	int i,n,len=0,j,k,q,q2,minv,x,bad_mask=0;
	in=fopen("adn.in","r");
	out=fopen("adn.out","w");
	fscanf(in,"%d",&n);
	for (i=1;i<=n;i++)
	{
		fscanf(in,"%s",s[i]+1);
		
		size[i]=gen_pi(i);
		len+=size[i];
	}
	for (i=1;i<=n;i++)
	{
		for (j=1;j<=n;j++)
			if (j!=i)
			{
				d[i][j]=-search(j,i);
				if (d[i][j]==-size[j])
					if (! (bad_mask & (1<<(j-1))))
						bad_mask+=1<<(j-1);
			}
	}
	q=(1<<n);
	for (i=0;i<q;i++)
		if ( !(bad_mask & i) )
		for (j=1;j<=n;j++,q2=1<<(j-1))
			if (i&q2)
			{
				minv=0;
				for (k=1;k<=n;k++)
					if (!(bad_mask & (1<<(k-1))) &&k!=j&& (i& (1<<(k-1))))
					{
						if (a[i-q2][k]+d[k][j]<minv)
						{
							minv=a[i-q2][k]+d[k][j];
							pred[i][j]=k;
						}
					}
				a[i][j]=minv;
			}
	minv=inf;
	q=((q-1)^bad_mask)+1;
	for (i=1;i<=n;i++)
	if (!(bad_mask & (1<<(i-1))))
	{
		if( a[q-1][i]<minv)
		{
			x=i;
			minv=a[q-1][i];
		}
	}
	afis(q-1,x);
	fclose(in);
	fclose(out);
	return 0;
}