Cod sursa(job #64704)

Utilizator crawlerPuni Andrei Paul crawler Data 4 iunie 2007 23:57:05
Problema ADN Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.27 kb
#include <cstdio>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

#define Nmax 32000
#define BITmax pow(18)
#define pow(q) (1<<(q))

char a[18][Nmax];
int pi[18][Nmax];
int sz[18], v[19][19],n;
int best[BITmax][18];
int before[BITmax][18];

void insert(int nod)
 {
	for(int i=0;i<n;++i) if(i^nod)
		for(int biti=0;biti<pow(n);++biti)
			if(best[biti^pow(nod)][nod] > best[biti][i] + sz[nod] - v[nod][i])
				{
					best[biti^pow(nod)][nod] = best[biti][i] + sz[nod] - v[nod][i];
					before[biti^pow(nod)][nod] = i;
				}			
 }

int main()
 {
	freopen("adn.in","r",stdin);
	freopen("adn.out","w",stdout);

	int i,j,k,l;

	scanf("%d\n", &n);

	for(i=0;i<n;++i)
		fgets(a[i],Nmax,stdin);

	for(i=0;i<n;++i)
		{
			sz[i] = strlen(a[i]) - 1;
			a[i][sz[i]] = 0;

			k = 0;

			for(j=1;j<sz[i];++j)
				{
                                
					while(k > 0 && a[i][k] != a[i][j])
						k = pi[i][k];
						
					if(a[i][k] == a[i][j])
						++k;
					pi[i][j] = k;
				}
				
		}		


	for(i=0;i<n;++i)
		for(j=0;j<n;++j)
			if(i != j)	
				{
					k = 0;
					for(l=0;l<sz[j];++l)
						{
							while(k > 0 && a[i][k] != a[j][l])
								k = pi[i][k];
							if(a[i][k] == a[j][l])
								++k;				
						}
					v[i][j] = k; 				
				}

    
    

/*
	for(i=0;i<n;++i)
		for(j=0;j<n;++j) if(i^j)		
			printf("%s + %s == %d\n",a[j],a[i],sz[i]+sz[j]-v[i][j]);
*/			

	memset(best,12345,sizeof(best));
	for(i=0;i<n;++i)
		{
			best[pow(i)][i] = sz[i];
			before[pow(i)][i] = 0;
		}	
                    

	for(i=0;i<n;++i)
		for(j=0;j<n;++j)
			insert(j);
/*
	for(i=0;i<n;++i)
		printf("ciclu care se termina in %d are lung %d\n",i,best[pow(n)-1][i]);	
*/
	//reconstr;
	
	int ok = 0,stare = pow(n)-1;
	for(i=1;i<n;++i)
		if(best[stare][i] < best[stare][ok])
			ok = i;
	
	vector<int> rec;
    rec.push_back(19);		
    rec.push_back(ok);	
	while(ok)
		{
			ok = before[stare][ok];
			stare ^= pow(ok);
			rec.push_back(ok);
		}
/*
	for(i=rec.size()-1;i>=0;--i)
		printf("%d ",rec[i]);
	printf("\n");
*/

	for(i=rec.size()-1;i>0;--i)
		{
            for(j=0;j<sz[rec[i]]-v[rec[i-1]][rec[i]];++j)                   
              printf("%c", a[rec[i]][j]);
		}

	return 0; 
 }