Cod sursa(job #572561)

Utilizator Andreid91Ciocan Andrei Andreid91 Data 5 aprilie 2011 13:44:02
Problema ADN Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.49 kb
#include<iostream.h>
#include<fstream.h>
#include<string.h>

#define inf 10000000

ofstream g("adn.out");

char s[20][30005],sol[30002];

int n,pi[30005],sw[30],l,dist[30][30],din[19][265000],best[19][265000],put[30],nr[265000],last[19][265000];

void preproc ()
{
	int i,j;
	
	i=1;
	while (i<=n)
		if (sw[i]==1)
		{
			strcpy(s[i],s[n]);
			sw[i]=sw[n];
			--n;
		}
		else
			i++;
}	
			

void solve()
{
	int i,len,j,max,conf,nod;
	
	put[0]=1;
	for (i=1;i<=n;i++)
		put[i]=put[i-1]*2;
	
	
	max=1<<n;
	
	for (i=1;i<=n;i++)
		for(j=1;j<=max;j++)
				din[i][j]=inf;
	
	for (i=1;i<=n;i++)
		din[i][put[i-1]]=strlen(s[i]);
	
	
	
	
	for (conf=0;conf<max;++conf)
		for (nod=1;nod<=n;nod++)
			if ((put[nod-1]^conf)<conf)
				for (i=1;i<=n;i++)
					if ((put[i-1]^conf)>conf)
						if (din[nod][conf]+dist[nod][i]<din[i][conf+put[i-1]])
						{
							din[i][conf+put[i-1]]=din[nod][conf]+dist[nod][i];
							last[i][conf+put[i-1]]=nod;
						}
								
}				

void kmp(int k)
{
	int i,j,p,m;
	p=0;pi[1]=0;
	m=strlen(s[k]);--m;
	for (i=2;i<=m;i++)
	{
		while (p>0 && s[k][p+1]!=s[k][i])
			p=pi[p];
	
		if (s[k][i]==s[k][p+1])
			++p;
		pi[i]=p;
	}
}

void potrivire(int q, int w)
{
	int i,p,m1,m2;
	
	m1=strlen (s[q])-1;
	m2=strlen(s[w])-1;
	
	p=0;
	for (i=1;i<=m1;i++)
	{
		while (p>0 && s[q][i]!=s[w][p+1])
			p=pi[p];
		
		if (s[w][p+1]==s[q][i])
			p++;
	
		if (p==m2)
		{
			p=pi[p];
			sw[w]=1;
		}
	}
	
	if (sw[w]==1)
		dist[q][w]=0;
	else
		dist[q][w]=m2-p;
}	

void distante()
{
	int i,j;
	for (i=1;i<=n;i++)
	{
		kmp(i);
		for (j=1;j<=n;j++)
			if (i!=j)
				potrivire(j,i);
	}
}

void write (int k, int conf)
{
	int i;
	if (last[k][conf]!=0)
	{
		write(last[k][conf],conf-put[k-1]);
		l=-1;
		for (i=strlen(s[k])-dist[last[k][conf]][k];i<strlen(s[k]);++i)
			sol[++l]=s[k][i];
		sol[++l]=0;
		g<<sol;
	}
	else
	{
		l=-1;
		for (i=1;i<strlen(s[k]);++i)
			sol[++l]=s[k][i];
		sol[++l]=0;
		g<<sol;
	}
}

void afisare()
{
	int i,min,poz;
	
	poz=1;min=din[1][put[n]-1];
	for (i=2;i<=n;i++)
		if (min>din[i][put[n]-1])
		{
			poz=i;
			min=din[i][put[n]-1];
		}
	write(poz,put[n]-1);
		
	g.close();
}

void citire()
{
	int i;
	char s1[30005];
	ifstream f("adn.in");
	f>>n;
	for (i=1;i<=n;i++)
	{
		s[i][0]='*';
		f>>s1;
		strcat(s[i],s1);
	}
	
	f.close();
}

int main()
{
	citire();
	distante();
	preproc();
	distante();
	solve();
	l=0;
	afisare();
	return 0;
}