Cod sursa(job #1061797)

Utilizator NaniteNanite Nanite Data 20 decembrie 2013 12:10:05
Problema ADN Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.37 kb
#include <cstdio>
#include <cstring>

const unsigned int maxSequenceLength = 30000, maxN = 18;
short *KMPTable;
char DNA[maxN][maxSequenceLength];
int N, st[maxN];
char s[maxN*maxSequenceLength];

void createKMPTable(char *pattern) {
	int k = -1, patternLength = strlen(pattern);
    KMPTable = new short[maxN*maxSequenceLength];
	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("adn.in", "r");
    fscanf(f, "%i", &N);

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

bool succesor(int k) {
    if(st[k] < N-1) {
        st[k]++;
        return true;
    }
    return false;
}

bool check(int k) {
    for(int i = 0; i < k; i++) {
        if(st[i] == st[k]) {
            return false;
        }
    }
    return true;
}

bool solutie(int k) {
    return k == N-1;
}

void init(int k) {
    st[k] = -1;
}

void process() {
    char *buffer = new char[maxN*maxSequenceLength];
    int x;
    for(int it = 0; it < N; it++) {
        strcat(buffer, DNA[st[it]] + kmpSearch(buffer, DNA[st[it]]));
    }

    if(strlen(s) == 0 || strlen(buffer) < strlen(s)) {
        strcpy(s, buffer);
    }
}

void backtracking() {
    bool e, v;
    int k = 0;
    init(k);

    while(k > -1) {
        do {
            e = succesor(k);
            if(e) {
                v = check(k);
            }
        }while(e && !v);

        if(e) {
            if(solutie(k)) {
                process();
            } else {
                k++;
                init(k);
            }
        } else {
            k--;
        }
    }
}


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

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

int main() {
    read();
    backtracking();
    write();

    return 0;
}