zoukankan      html  css  js  c++  java
  • 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;
    }
    

      

  • 相关阅读:
    android listview simpleAdaper
    android appwigt
    android shortcut &livefoulder
    android 命令行
    React Native for Android 学习笔记
    android dialog
    android Menu
    Android Gallery
    Android Listview
    Android
  • 原文地址:https://www.cnblogs.com/yejinru/p/2821210.html
Copyright © 2011-2022 走看看