Cod sursa(job #974198)

Utilizator marius135Dumitran Adrian Marius marius135 Data 16 iulie 2013 16:56:57
Problema ADN Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.42 kb
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<string>
#include<vector>

using namespace std;

#define maxl 30005

string sir[20];
int fail[20][maxl];
int sel[20];
int mat[20][20];
int cost[1<<18][18];
int last[1<<18][18];
int cate[1<<18][18];


void prekmp( string sir, int * rez) {
     
     
    int n = sir.size(), i = 0, j = -1;
    rez[0] = -1;
    while( i < n ) {
        while( j >= 0 && sir[i] != sir[j]) // daca elementele nu sunt compatibile si nu am ajuns inca la inceput
            j = rez[j]; // j ia urmataorea valoare posibila
        i++; j++;
        rez[i] = j;
    }
}

int kmp( string sir1, string sir2, int *rez) {
    int i = 0, j = 0;
    int n = sir1.size(), m = sir2.size();
	int nr = 0;
	if( m > n ) return 0;
    while (i < n ) {
        while(j >= 0 && sir1[i] != sir2[j]) 
            j = rez[j];
        i++; j++;
        if( j == m) {
            nr++;
            j = rez[j];
        }
    }
    return nr;
}

int semikmp( string sir1, string sir2, int *rez) {
    int i = 0, j = 0;
    int n = sir1.size(), m = sir2.size();
	int nr = 0;

    while (i < n ) {
        while(j >= 0 && sir1[i] != sir2[j]) 
            j = rez[j];
        i++; j++;
        if( j == m) {
            nr++;
            j = rez[j];
        }
    }
    return j;
}

int main() {
	
	
	
	freopen("ADN.in", "r", stdin);
	freopen("ADN.out", "w", stdout);
	
	int N;
	cin>>N;
	
	for( int i = 0; i < N; ++i) {
		cin>>sir[i];
		prekmp( sir[i], fail[i]);
	}
	return 0;
	return 0;
	for( int i = 0; i < N; ++i) {
		for( int j = i + 1; j < N; ++j) {
			sel[j] += kmp( sir[i], sir[j], fail[j]);
			sel[i] += kmp( sir[j], sir[i], fail[i]);
				
		}
	}
	
	int laast = 0;
	for( int i = 0; i < N; ++i) {
		if( sel[i] == 0) {
			sir[laast++] = sir[i];
			for( size_t j = 0; j <= sir[i].size(); ++j) {
				fail[laast - 1][j] = fail[i][j];
			}
		}
	}
	
	
	N = laast;
	
	for( int i = 0; i < N; ++i) {
		for( int j = i + 1; j < N; ++j) {
			mat[i][j] += semikmp( sir[i], sir[j], fail[j]);
			mat[j][i] += semikmp( sir[j], sir[i], fail[i]);
				
		}
	}
	/*
	cout<<N<<endl;
	for( int i = 0; i < N; ++i)
		cout<<sir[i] <<endl;
	
	*/
	memset( cost, 111, sizeof(cost));
	for( int i = 0; i < N; ++i) {
		cost[ 1<<i][i] = sir[i].size();
		last[ 1<<i][i] = i;
		cate[ 1<<i ][i] = sir[i].size();
	}
	for( int i = 1; i < (1<<N) - 1; ++i)  {
		for( int j = 0; j < N; ++j) {
			if( (i & ( 1<< j)) == 0)
				continue;
			for( int k = 0; k < N; ++k){
				if( i & (1<<k) )
					continue;
				if( cost[i ^(1<<k)][k] > cost[i][j] + sir[k].size() - mat[j][k]) {
					cost[i ^(1<<k)][k] = cost[i][j] + sir[k].size() - mat[j][k];
					last[i ^(1<<k)][k] = j;
					cate[i ^(1<<k)][k] =  sir[k].size() - mat[j][k];
					
				}
			}
			
		}
	}
	int optim = 1000000000, cine = -1;
	for( int i = 0; i < N; ++i)
		if( cost[(1<<N)-1][i] < optim) {
			optim = cost[(1<<N)-1][i];
			cine = i;
		}
	
	laast = (1<<N) - 1;
	string result;
	vector<string> temp_rez;
	while( laast ) {
		
		int new_index = cine;
		int new_length = cate[laast][cine];
		string new_word( sir[new_index].end() - new_length , sir[new_index].end());
		temp_rez.push_back(new_word);
		int temp_cine = last[laast][cine];
		laast ^= (1<<cine);
		cine = temp_cine;
		
	}
	for( int i = N - 1; i >= 0; i--)
		result += temp_rez[i];
	//cout<<optim<<endl;
	cout<<result;
		
		
	
	
	
}