Cod sursa(job #1069791)

Utilizator NaniteNanite Nanite Data 30 decembrie 2013 15:03:32
Problema ADN Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.53 kb
#include <cstdio>
#include <cstring>

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

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

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

	for (int 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);

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

	for (int 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) {
            delete kmpTable;
			return -1;
		}
	}

    delete kmpTable;
	return k+1;
}

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

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

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

void write() {
    FILE *f = fopen(out, "w");

    fprintf(f, "%s", DNA+N-1);
}

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

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

unsigned int indexOfMax(unsigned short index) {
    unsigned short maxIndex = 0;

    while(eliminated[maxIndex]) {
        maxIndex++;
    }

    for(unsigned short i = maxIndex+1; i < N; i++) {
        if(!eliminated[i] && graph[i][index] > graph[maxIndex][index]) {
            maxIndex = i;
        }
    }

    return maxIndex;
}

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

void mergeDNASequences() {
    unsigned short x;

    for(unsigned short i = 0; i < N-1; i++) {
        if(!eliminated[i]) {
            x = indexOfMax(i);
            strcat(DNA[x], DNA[i] + graph[x][i]);
            copyGraphLine(x, i);
            eliminated[i] = true;
        }
    }
}

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

    return 0;
}