Cod sursa(job #1097139)

Utilizator NaniteNanite Nanite Data 3 februarie 2014 01:17:07
Problema ADN Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.09 kb
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>

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

long graph[maxN][maxN];
unsigned int N;
char DNA[maxN][maxDNASequenceLength*maxN];
long *kmpTable = new long[maxN*maxDNASequenceLength];
unsigned int mask;

struct coordonates{
    unsigned int x, y;
    int value;
}nodes[maxN*maxN];
unsigned int it;

void createKMPTable(char *pattern) {
	long k = -1, patternLength = strlen(pattern);
    memset(kmpTable, 0, 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;
	}
}

bool eliminated(unsigned int n) {
    return mask & (1 << n);
}

void eliminate(unsigned int n) {
    mask |= (1 << n);
}

long 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) {
			return -1;
		}
	}

	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(i) && !eliminated(j)) {
                graph[i][j] = kmpSearch(DNA[i], DNA[j]);
                if(graph[i][j] == -1) {
                    eliminate(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(i)) {
            x++;
        }
    }

    return x == 1;
}

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

void mergeDNASequences() {
    unsigned int maxX, maxY;
    int i = it-1;


    while(!finished()) {
        strcat(DNA[nodes[i].x], DNA[nodes[i].y] + nodes[i].value);
        eliminate(nodes[i].y);
        i--;
    }

    write(DNA[nodes[i+1].x]);
}

void convertGraph() {
    for(unsigned int i = 0; i < N; i++) {
        for(unsigned int j = 0; j < N; j++) {
            nodes[it].x = i;
            nodes[it].y = j;
            nodes[it].value = graph[i][j];
            it++;
        }
    }
}

bool cmp(coordonates a, coordonates b) {
    return a.value < b.value;
}

int main() {
    read();
    createGraph();
    convertGraph();
    std::sort(nodes, nodes+it, cmp);
    mergeDNASequences();

    return 0;
}