• UVa 1449


    题目大意:给出多个字符串模板,并给出一个文本串,求在文本串中出现最多的模板,输出最多的次数并输出该模板(若有多个满足,则按输入顺序输出)。

    思路:赤裸裸的 AC自动机,上模板。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    #include<cmath>
    #include<map>
    using namespace std;
    #define INF 0x7fffffff
    
    char s[160][80],T[1000010];
    int nz,cnt,ch[15000][30],num[160],val[315000];
    int f[315000],last[315000];
    
    void insert(char a[],int k){
    	int i,j,len = strlen(a),u = 0;
    	for(i=0;i<len;i++){
    		int v = a[i] - 'a' ;
    		if(!ch[u][v]){
    			memset(ch[nz],0,sizeof(ch[nz]));
    			val[nz]=0;
    			ch[u][v] = nz++;
    		}
    		u = ch[u][v];
    	}
    	val[u] = k;
    }
    
    void getFail(){
    	int i;
    	queue<int> Q;
    	while(!Q.empty())
    		Q.pop();
    	f[0] = 0;
    	for(i=0;i<26;i++)
    	    if(ch[0][i]){
    	    	f[ch[0][i]] = 0;
    			Q.push(ch[0][i]);
    			last[ch[0][i]] = 0;	
    	    }
    	while(!Q.empty()){
    		int r = Q.front();
    		Q.pop();
    		for(i=0;i<26;i++){
    			int v = ch[r][i];
    			if(v){
    				Q.push(v);
    				int p = f[r];
    				while(p && !ch[p][i])
    				    p = f[p];
    				f[v] = ch[p][i];
    				last[v] = val[f[v]] ? f[v] : last[f[v]];
    			}
    		}
    	}
    }
    
    void print(int i){
    	if(i){
    //		printf("%d ",val[i]); 
    		num[val[i]]++;
    		print(last[i]);
    	}
    }
    
    void find(){
    	int i,j;
    	int len = strlen(T);
    	int u = 0;
    	for(i=0;i<len;i++){
    		int v = T[i] - 'a';
    		while(u && !ch[u][v]) u = f[u];
    		u = ch[u][v];
    		if(val[u]) print(u);
    		else if(last[u]) print(last[u]);
    	} 
    }
    
    int main(){
    	int n,i,j;
    	while(scanf("%d",&n) && n){
    		nz = 1;
    		memset(val,0,sizeof(val));
    		memset(ch[0],0,sizeof(ch));
    		memset(num,0,sizeof(num));
    		for(i=1;i<=n;i++){
    			scanf("%s",s[i]);
    			insert(s[i],i);
    		}
    		scanf("%s",T);
    		getFail();
    		find();
    		int MAX = 0;
    		for(i=1;i<=n;i++)
    			MAX = max(MAX,num[i]);
    		printf("%d
    ",MAX);
    		for(i=1;i<=n;i++)
    		    if(num[i] == MAX)
    		        printf("%s
    ",s[i]);
    	}
    
    	return 0;
    }
    
  • 相关阅读:
    hdu 4033Regular Polygon(二分+余弦定理)
    hdu 4405Aeroplane chess(概率DP)
    hdu 3853LOOPS (概率DP)
    网络编程基础(转)
    网络编程socket基本API详解(转)
    网络编程之socket(转)
    cf(#div1 B. Dreamoon and Sets)(数论)
    cf(#div1 A. Dreamoon and Sums)(数论)
    hdu 1805Expressions(二叉树构造的后缀表达式)
    hdu1710(Binary Tree Traversals)(二叉树遍历)
  • 原文地址:https://www.cnblogs.com/jxgapyw/p/4780584.html
Copyright © 2020-2023  润新知