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;
}

  

原文地址:https://www.cnblogs.com/yejinru/p/2821210.html