Pagini recente » Cod sursa (job #1953463) | Cod sursa (job #2000197) | Diferente pentru teorema-chineza-a-resturilor intre reviziile 71 si 89 | Cod sursa (job #2752279) | Cod sursa (job #1736263)
#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], k, len,
jj;
for( i = 0 ; i < n ; i++ ){
len = strlen(secv[i]);
metaData[i][0] = 0;
jj=0;
k = 1;
while( k < len ){
//printf("k=%d ; jj=%d \n", k , jj);
if( secv[i][k] == secv[i][jj] ){
jj++;
metaData[i][k] = jj;
k++;
} else if( jj > 0 )
jj = metaData[i][jj-1];
else {
metaData[i][k] = 0;
k++;
}
}
}
unsigned short costs[n][n], wi, ti, lenMax,
lenMin, startPos;
unsigned char deElim[n], max, min;
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 = startPos = 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];
startPos = ti;
} else {
ti++;
startPos = ti;
}
if( wi == lenMin)
deElim[min] = 1;
else{
//TO DO calculeaza cost[max][min] si cost[min][max]
//max <--- min
costs[max][min] = lenMax - startPos;
//min <--- max
wi = startPos = 1;
ti = 0;
while( wi < lenMin ){
if( secv[min][wi] == secv[max][ti] ){
wi++;
ti++;
} else if( ti != 0 ) {
ti = metaData[max][ti-1];
startPos = wi;
} else {
wi++;
startPos = wi;
}
}
costs[min][max] = lenMin - startPos;
}
}
n++;
unsigned char indexes[n];
for( i = 0 ; i < n ; i++ )
indexes[i] = i;
for( i = 0 ; i < n ; i++ )
if( deElim[i] ){
n--;
for( j = i ; j < n ; j++ )
indexes[j] = indexes[j+1];
}
//for( i = 0 ; i < n ; i++ )
//printf("indexes[%d]=%d\n", i , indexes[i]);
//ESTE BINE
unsigned int mask, maxLen = (1<<n)-1;
//printf("maxLen=%d\n", maxLen);
int variante[n][maxLen];
unsigned char parinte[n][maxLen];
//memset((void*)variante, 0 , n*maxLen*sizeof(unsigned int));
for( i = 0 ; i < n ; i++ )
for( mask = 0 ; mask <= maxLen ; mask++ )
variante[i][mask] = INT_MIN;
//seteaza ce se stie
for( i = 0 ; i < n ; i++ ){
for( j = 0 ; j < i ; j++ ){
variante[i][(1<<i)+(1<<j)] = costs[indexes[i]][indexes[j]];
parinte[i][(1<<i)+(1<<j)] = j;
}
for( j = i+1 ; j < n ; j++ ){
variante[i][(1<<i)+(1<<j)] = costs[indexes[i]][indexes[j]];
parinte[i][(1<<i)+(1<<j)] = j;
}
}
for( mask = 0 ; mask <= maxLen ; mask ++ )
for( i = 0 ; i < n ; i++ )
if( mask & ( 1 << i ) )
for( j = 0 ; j < n ; j++ )
if( ( mask & ( 1 << j ) ) &&
variante[j][mask ^ ( 1 << i )] != INT_MIN &&
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 )];
parinte[i][mask] = j;
}
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");
for( i = 0 ; i < n ; i++ ){
//printf("%s (%d) ", secv[indexes[j]] + deElim[1] , indexes[j]);
fprintf(fi,"%s", secv[indexes[j]] + ti );
deElim[0] = j;
j = parinte[j][mask];
ti = costs[indexes[deElim[0]]][indexes[j]];
mask -= (1 << deElim[0]);
}
//printf("\n");
fclose(fi);
/*for( i = 0 ; i < n ; i++ ){
printf("%d: ", i );
for( k = 0 ; k < strlen(secv[i]) ; k++ )
printf("%c ", secv[i][k] );
printf("\n");
printf("%d: ", i );
for( k = 0 ; k < strlen(secv[i]) ; k++ )
printf("%d ", metaData[i][k] );
printf("\n");
}*/
/*printf("deElim:\n");
for( i = 0 ; i < n ; i++ )
printf("%d ", deElim[i]);
printf("\ncosts:\n");
for( i = 0 ; i < n ; i++ ){
for( j = 0 ; j < n ; j++ )
if( i == j )
printf("null\n");
else{
printf("<( %s ; %s ) | %d >\n", secv[i], secv[j], costs[i][j]);
}
printf("\n");
}*/
}