Cod sursa(job #1077263)

Utilizator NaniteNanite Nanite Data 11 ianuarie 2014 07:01:54
Problema ADN Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.98 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) {
            delete[] kmpTable;
			return -1;
		}
	}

    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) {
    x = 0; y = 0;
    while(eliminated & (1 << x)) {
        x++;
    }
    while(eliminated & (1 << y)) {
        y++;
    }
}

void mergeDNASequences() {
    unsigned int maxX, maxY;



    while(!finished()) {
            init(maxX, maxY);
            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] > graph[maxX][maxY]) {
                            maxX = j;
                            maxY = k;
                        }
                    }
                }
            }
            strcat(DNA[maxX], DNA[maxY] + graph[maxX][maxY]);
            copyGraphLine(maxY, maxX);
            eliminated |= (1 << maxY);
    }

    write(DNA[maxX]);
}

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

    return 0;
}