input
n 1<=n<=150
word1
word2
...
wordn
1<=len(wirdi)<=70
s 1<=len(s)<=1000000
output
最多出现次数
出现最多的串,按输入顺序输出,可能出现相同串,也要输出
做法:用一个end数组记下每个串结尾的字符的下标,对应val为1,每次找到就将val++,然后找到最大的val,输出最大val对应的字符串
1 #include <cstdio> 2 #include <queue> 3 #include <cstring> 4 #include <iostream> 5 #include <cstdlib> 6 #include <algorithm> 7 #include <vector> 8 #include <map> 9 #include <set> 10 #include <ctime> 11 #include <cmath> 12 #include <cctype> 13 #define MAX 100000 14 #define LL long long 15 int cas=1,T,n,sz,maxt,last[160*80],f[160*80],ch[160*80][26],val[160*80],end[160]; 16 char s[MAX*10+10],word[160][80]; 17 int idx(char&c) {return c-‘a‘;} 18 void inittrie() 19 { 20 memset(ch[0],0,sizeof(ch[0])); 21 sz=1; 22 val[0]=0; 23 } 24 int insert(char*s) 25 { 26 int u=0; 27 for(;*s;s++) 28 { 29 int c=idx(*s); 30 if(!ch[u][c]) 31 { 32 memset(ch[sz],0,sizeof(ch[0])); 33 val[sz]=0; 34 ch[u][c]=sz++; 35 } 36 u=ch[u][c]; 37 } 38 val[u]=1; 39 return u; 40 } 41 void getFail() 42 { 43 std::queue<int>q; 44 f[0]=0; 45 for(int c=0;c<26;c++) 46 { 47 int u=ch[0][c]; 48 if(u) { f[u]=0;q.push(u);last[u]=0; } 49 } 50 while(!q.empty()) 51 { 52 int r=q.front();q.pop(); 53 for(int c=0;c<26;c++) 54 { 55 int u=ch[r][c]; 56 if(!u){ ch[r][c]=ch[f[r]][c];continue; } 57 q.push(u); 58 int v=f[r]; 59 while(v&&!ch[v][c]) v=f[v]; 60 f[u]=ch[v][c]; 61 last[u]=val[f[u]]?f[u]:last[f[u]]; 62 } 63 } 64 } 65 void print(int j) 66 { 67 if(j) 68 { 69 if(val[j]) val[j]++; 70 print(last[j]); 71 } 72 } 73 void find(char*s) 74 { 75 int n=strlen(s); 76 int j=0; 77 for(int i=0;i<n;i++) 78 { 79 int c=idx(s[i]); 80 j=ch[j][c]; 81 //printf("val[%d]=%d\n",j,val[j]); 82 //if(val[j]) val[j]++; 83 //else if(last[j]) val[last[j]]++; 84 if(val[j]) print(j); 85 else if(last[j]) print(last[j]); 86 } 87 } 88 int main() 89 { 90 //freopen("/home/user/桌面/in","r",stdin); 91 //scanf("%d\n",&T); 92 while(scanf("%d",&n)==1&&n) 93 { 94 inittrie(); 95 for(int i=0;i<n;i++) 96 { 97 scanf("%s",word[i]); 98 end[i]=insert(word[i]); 99 } 100 maxt=-1; 101 // for(int i=0;i<n;i++) printf("%d %d %s\n",end[i],val[end[i]],word[i]); 102 getFail(); 103 scanf("%s",s); 104 find(s); 105 for(int i=0;i<n;i++) maxt=std::max(maxt,val[end[i]]); 106 printf("%d\n",maxt-1); 107 for(int i=0;i<n;i++) if(val[end[i]]==maxt) puts(word[i]); 108 } 109 //printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC); 110 return 0; 111 }
时间: 2024-10-15 05:47:07