BZOJ 1819: [JSOI]Word Query电子字典

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1819

分析:
暴力枚举需要添加、删除以及替换的字符,然后建立trie树进行判断是否存在该字符串,然后利用trie树存的信息进行判重

时间貌似有点慢。

329611 yejinru 1819 Accepted 21468 kb 1232 ms C++/Edit 2193 B 2012-12-16 17:34:39
#include <cstdio>

#include <iostream>

#include <cstring>



using namespace std;



const int kind = 26;

const int X = 25;



#define debug puts("here");



int m,n,tot;



struct trie{

	trie *p[kind];

	int is,id; //is 用于判重,id用于标记是否有单词在这个节点结束

	trie(){

		memset(p,NULL,sizeof(p));

		is = id = 0;

	}

};



void insert(trie *t,char *s){

	int id;

	for(int i=0;s[i];i++){

		id = s[i]-'a';

		if(t->p[id]==NULL)

			t->p[id] = new trie();

		t = t->p[id];

	}

	t->is = t->id = tot;

}



int has(trie *t,char *s){ //判断是否存在字符串s

	int c = 0;

	for(int i=0;s[i];i++){

		c = s[i]-'a';

		if(t->p[c]==NULL)

			return 0;

		t = t->p[c];

	}

	if(t->id)

		return 1;

	return 0;

}



int find(trie *t,char *s,int id){ //用于判断是否存在字符串s并且s没被统计过,id在这用于判重

	int c = 0;

	for(int i=0;s[i];i++){

		c = s[i]-'a';

		if(t->p[c]==NULL)

			return 0;

		t = t->p[c];

	}

	if(t->id==0||t->is==id) //不存在单词或者已经算过一次了

		return 0;

	t->is = id;

	return 1;

}



int main(){

	int n , m;

	while(cin>>n>>m){

		tot = 10000000;



		trie * root = new trie();

		char s[X],str[X];

		

		for(int i=0;i<n;i++){

			scanf("%s",s);

			insert(root,s);

		}

		

		while(m--){

			int ans = 0;

			scanf("%s",str);



			if(has(root,str)){

				puts("-1");

				continue;

			}



			tot --;



			int len = strlen(str);



			for(int i=0;i<len;i++){	// delete

				strcpy(s,str);

				

				for(int j=i+1;j<len;j++)

					s[j-1] = str[j];

				s[len-1] = '\0';

				

				ans += find(root,s,tot);

			}



			for(int i=0;i<len;i++){	// change

				for(int j=0;j<26;j++){

					if(str[i]==j+'a')

						continue;



					strcpy(s,str);

					s[i] = j+'a';

					

					ans += find(root,s,tot);

				}

			}



			for(int i=0;i<=len;i++){ // add

				for(int j=0;j<26;j++){

					

					s[i] = j+'a';

					for(int k=0;k<i;k++)

						s[k] = str[k];

					for(int k=i;k<len;k++)

						s[k+1] = str[k];

					s[len+1] = '\0';



					ans += find(root,s,tot);

				}

			}

			printf("%d\n",ans);

		}

	}

	return 0;

}

  

你可能感兴趣的:(query)