Cod sursa(job #1076430)

Utilizator NaniteNanite Nanite Data 10 ianuarie 2014 10:23:34
Problema ADN Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.16 kb
#include <cstdio>
#include <cstring>
#include <cstdlib>

const unsigned short maxN = 18;
const unsigned int maxDNASequenceLength = 30000;
const char *in = "adn.in", *out = "adn.out";

int graph[maxN][maxN];
unsigned int N;
char DNA[maxN][maxDNASequenceLength*maxN];
long *kmpTable;
unsigned int eliminated;

void createKMPTable(char *pattern) {
	long k = -1, patternLength = strlen(pattern);
    kmpTable = new long[maxN*maxDNASequenceLength];
	kmpTable[0] = k;

	for ( long i = 1; i < patternLength; i++) {
		while (k > -1 && pattern[k+1] != pattern[i])
			k = kmpTable[k];
		if (pattern[i] == pattern[k+1])
			k++;
		kmpTable[i] = k;
	}
}

int kmpSearch(char *target, char *pattern) {
	createKMPTable(pattern);

	long k = -1, targetLength = strlen(target), patternLength = strlen(pattern);

	for (long i = 0; i < targetLength; i++) {
		while (k > -1 && pattern[k+1] != target[i])
			k = kmpTable[k];
		if (target[i] == pattern[k+1])
			k++;
		if (k == patternLength - 1) {
            //free(kmpTable);
            delete kmpTable;
			return -1;
		}
	}

    //free(kmpTable);
    delete kmpTable;
	return k+1;
}

void read() {
    FILE *f = fopen(in, "r");

    fscanf(f, "%u", &N);

    for(unsigned int i = 0; i < N; i++) {
        fscanf(f, "%s", DNA[i]);
    }
}

void write(char c[]) {
    FILE *f = fopen(out, "w");

    fprintf(f, "%s", c);
}

void createGraph() {
    for(unsigned int i = 0; i < N; i++) {
        graph[i][i] = -1;
    }

    for(unsigned int i = 0; i < N; i++) {
        for(unsigned int j = 0; j < N; j++) {
            if(i != j && !(eliminated & (1 << i)) && !(eliminated & (1 << j))) {
                graph[i][j] = kmpSearch(DNA[i], DNA[j]);
                if(graph[i][j] == -1) {
                    eliminated |= (1 << j);
                }
            }
        }
    }
}

void copyGraphLine(unsigned int lineA, unsigned int lineB) {
    for(unsigned int i = 0; i < N; i++) {
        graph[lineB][i] = graph[lineA][i];
    }
}

bool finished() {
    int x = 0;
    for(unsigned int i = 0; i < N; i++) {
        if(!(eliminated & (1 << i))) {
            x++;
        }
    }

    return x == 1;
}

void init(unsigned int &x, unsigned int &y, long &m) {
    x = 0; y = 0;
    while(eliminated & (1 << x)) {
        x++;
    }
    while(eliminated & (1 << y)) {
        y++;
    }

    m = graph[x][y];
}

void mergeDNASequences() {
    unsigned int maxX, maxY;

    long max;
    init(maxX, maxY, max);


    while(!finished()) {
            for(unsigned int j = 0; j < N; j++) {
                if(!(eliminated & (1 << j))) {
                    for(unsigned int k = 0; k < N; k++) {
                        if(!(eliminated & (1 << k)) && graph[j][k] > max) {
                            max = graph[j][k];
                            maxX = j;
                            maxY = k;
                        }
                    }
                }
            }
            strcat(DNA[maxX], DNA[maxY] + graph[maxX][maxY]);
            copyGraphLine(maxY, maxX);
            eliminated |= (1 << maxY);
            init(maxX, maxY, max);
    }

    write(DNA[maxX]);
}

int main() {
    read();
    createGraph();
    mergeDNASequences();

    return 0;
}