Pagini recente » Cod sursa (job #1944288) | Cod sursa (job #2153279) | Cod sursa (job #199720) | Cod sursa (job #655238) | Cod sursa (job #1737015)
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <stdlib.h>
void main(){
FILE * fi = fopen("adn.in","rt");
unsigned char n, i, j;
fscanf( fi, "%hhd\n" , &n);
char secv[n][30000];
n--;
for( i = 0 ; i < n ; i++ )
fscanf(fi,"%s\n",secv[i]);
fscanf(fi,"%s",secv[n]);
fclose(fi);
n++;
unsigned short metaData[n][30000], ti, len,
wi;
for( i = 0 ; i < n ; i++ ){
len = strlen(secv[i]);
metaData[i][0] = 0;
wi=0;
ti = 1;
while( ti < len ){
if( secv[i][ti] == secv[i][wi] ){
wi++;
metaData[i][ti] = wi;
ti++;
} else if( wi > 0 )
wi = metaData[i][wi-1];
else {
metaData[i][ti] = 0;
ti++;
}
}
}
unsigned short costs[n][n], lenMax,
lenMin;
unsigned char deElim[n], max, min, k = 0;
for( i = 0 ; i < n ; i++ )
deElim[i] = 0;
n--;
for( i = 0 ; i < n ; i++ )
for( j = i + 1 ; j <= n && !deElim[i] ; j++ )
if( !deElim[j] ){
if( strlen(secv[i]) > strlen(secv[j]) ){
max = i;
min = j;
} else {
max = j;
min = i;
}
wi = ti = len = 0;
lenMax = strlen(secv[max]);
lenMin = strlen(secv[min]);
while( ti < lenMax && wi < lenMin )
if( secv[min][wi] == secv[max][ti] ){
wi++;
ti++;
} else if( wi != 0){
wi = metaData[min][wi-1];
len = ti;
} else {
ti++;
len = ti;
}
if( wi == lenMin){
deElim[min] = 1;
k++;
}
else{
costs[max][min] = lenMax - len;
wi = len = 1;
ti = 0;
while( wi < lenMin ){
if( secv[min][wi] == secv[max][ti] ){
wi++;
ti++;
} else if( ti != 0 ) {
ti = metaData[max][ti-1];
len = wi;
} else {
wi++;
len = wi;
}
}
costs[min][max] = lenMin - len;
}
}
n++;
unsigned char indexes[n-k];
i = j = 0;
while( i < n ){
if(!deElim[i]){
indexes[j] = i;
j++;
}
i++;
}
n = j;
unsigned int mask, maxLen = 1<<n;
int variante[n][maxLen];
unsigned char after[n][maxLen];
for( i = 0 ; i < n ; i++ )
for( mask = 0 ; mask < maxLen ; mask++ )
variante[i][mask] = INT_MIN;
for( i = 0 ; i < n ; i++ ){
for( j = 0 ; j < i ; j++ ){
variante[i][(1<<i)+(1<<j)] = costs[indexes[i]][indexes[j]];
after[i][(1<<i)+(1<<j)] = j;
}
for( j = i+1 ; j < n ; j++ ){
variante[i][(1<<i)+(1<<j)] = costs[indexes[i]][indexes[j]];
after[i][(1<<i)+(1<<j)] = j;
}
}
for( mask = 3 ; mask < maxLen ; mask ++ )
for( i = 0 ; i < n ; i++ )
if( mask & ( 1 << i ) ){
for( j = 0 ; j < i ; j++ ){
/*printf("i=%d j=%d mask=%d indexes[i]=%d indexes[j]=%d (%d < %d + %d)\n",
i , j , mask ,indexes[i], indexes[j] ,
variante[i][mask],
costs[indexes[i]][indexes[j]],
variante[j][mask ^ ( 1 << i )]);*/
if( ( mask & ( 1 << j ) ) &&
variante[i][mask] < costs[indexes[i]][indexes[j]] +
variante[j][mask ^ ( 1 << i )] ){
variante[i][mask] = costs[indexes[i]][indexes[j]] +
variante[j][mask ^ ( 1 << i )];
after[i][mask] = j;
}
}
for( j = i + 1 ; j < n ; j++ ){
if( ( mask & ( 1 << j ) ) &&
variante[i][mask] < costs[indexes[i]][indexes[j]] +
variante[j][mask ^ ( 1 << i )] ){
variante[i][mask] = costs[indexes[i]][indexes[j]] +
variante[j][mask ^ ( 1 << i )];
after[i][mask] = j;
}
}
}
maxLen--;
mask = variante[0][maxLen];
j = 0;
for( i = 1 ; i < n ; i++ )
if( variante[i][maxLen] > mask ){
mask = variante[i][maxLen];
j = i;
}
mask = maxLen;
ti = 0;
fi = fopen("adn.out","wt");
while(1){
fprintf(fi,"%s", secv[indexes[j]] + ti );
n--;
if( n == 0 )
break;
deElim[0] = j;
j = after[j][mask];
ti = costs[indexes[deElim[0]]][indexes[j]];
mask -= (1 << deElim[0]);
}
fclose(fi);
}