Cod sursa(job #187834)

Utilizator scvalexAlexandru Scvortov scvalex Data 5 mai 2008 16:53:08
Problema Abc2 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.34 kb
#include <iostream>
#include <fstream>

using namespace std;

/*
 * Un trie
 *
 * Folosesc aici un arbore de prefixuri.
 * El tine prefixurile pe muchiile sale.
 * Adica o muchie are pe ea un a daca si
 * numai daca, pe un drum de la radacina
 * la un nod, apare un a pe aceea acolo.
 *
 * De exemplu, abba este stocat ca:
 *
 *             *
 *            /
 *          a/
 *          /
 *         *
 *         |
 *        b|
 *         |
 *         *
 *         |
 *        b|
 *         |
 *         *
 *        /
 *      a/
 *      /  
 *     #
 *
 * Unde:
 *   * - un nod in care NU se termina un cuvant
 *   # - un nod in care se termina un cuvant
 *
 * Sigur, se pot salva mai multe cuvinte in acelasi trie.
 * Textele abba, bbca, abcb, bbca si aaaa sunt salvate ca:
 *
 *                       *
 *                    /  |
 *                  a/   |b
 *                  /    |
 *                 *     *
 *               / |     |
 *             a/ b|     |b
 *             /   |     |
 *            *    *     *
 *           /     |\     \
 *         a/     b| \c   c\
 *         /       |  \     \
 *        *        *   *     *
 *       /        /    |    /
 *     a/       a/    b|  a/
 *     /        /      |  /
 *    #        #       # #
 *
 */

typedef struct trie_s {
	bool cuvantP;
	struct trie_s *a, *b, *c;
} Trie;

char text[10000001],
     cuvant[21];
Trie t;
int cnt(0);

void insert_into_trie(char *cuvant)
{
	Trie *r = &t;
	for (char *c = cuvant; *c; ++c)
		if (*c == 'a') {
			if (!r->a)
				r->a = new Trie;
			r = r->a;
		} else if (*c == 'b') {
			if (!r->b)
				r->b = new Trie;
			r = r->b;
		} else if (*c == 'c') {
			if (!r->c)
				r->c = new Trie;
			r = r->c;
		}
	r->cuvantP = true;
}

void check_trie(char *text)
{
	Trie *r = &t;
	for (char *c = text; *c; ++c) {
		if (*c == 'a') {
			if (!r->a)
				break;
			r = r->a;
		} else if (*c == 'b') {
			if (!r->b)
				break;
			r = r->b;
		} else if (*c == 'c') {
			if (!r->c)
				break;
			r = r->c;
		}
		if (r->cuvantP)
			++cnt;
	}
}

int main(int argc, char *argv[]) 
{
	FILE *fi = fopen("abc2.in", "r");
	fscanf(fi, "%s\n", text);
	//cout << text << endl;
	while (!feof(fi)) {
		fscanf(fi, "%s\n", cuvant);
		//cout << cuvant << endl;
		insert_into_trie(cuvant);
	}
	fclose(fi);

	for (char *c = text; *c; ++c)
		check_trie(c);

	ofstream fout("abc2.out");
	fout << cnt << endl;
	fout.close();

	return 0;
}