Description
Input
Output
Sample Input
3 AA BB CC ooxxCC%dAAAoen....END
Sample Output
AA: 2 CC: 1
Hint
Hit: 题目描述中没有被提及的所有情况都应该进行考虑。比如两个病毒特征码可能有相互包含或者有重叠的特征码段。 计数策略也可一定程度上从Sample中推测。
这题就是记录的时候得加标记,然后因为母串有别的字符,所以在这WA了两发才知道哪错了……
#include <iostream> #include <cstdio> #include <fstream> #include <algorithm> #include <cmath> #include <deque> #include <vector> #include <list> #include <queue> #include <string> #include <cstring> #include <map> #include <stack> #include <set> #define PI acos(-1.0) #define mem(a,b) memset(a,b,sizeof(a)) #define sca(a) scanf("%d",&a) #define pri(a) printf("%d\n",a) #define MM 2000005 #define MN 250005 #define INF 10000007 using namespace std; char str[MM],ss[MN][51],s1[MM]; int next[MN],last[MN],sum[MN]; struct Trie { int ch[MN][27],val[MN],sz; int idx(char c) { return c-'A'; } void reset() { sz=1; mem(ch,0); mem(val,0); } void insert(char *s,int j) { int u=0,i,c,l=strlen(s); for(i=0; i<l; i++) { c=idx(s[i]); if(!ch[u][c]) ch[u][c]=sz++; u=ch[u][c]; } val[u]=j; } } T; void getfail() { queue<int>q; int c,u; next[0]=0; for(c=0; c<26; c++) { u=T.ch[0][c]; if(u) { next[u]=0; q.push(u); last[u]=0; } } while(!q.empty()) { int r=q.front(); q.pop(); for(c=0; c<26; c++) { u=T.ch[r][c]; if(!u) { T.ch[r][c]=T.ch[next[r]][c]; //优化next continue; } q.push(u); int v=next[r]; while(v&&!T.ch[v][c]) v=next[v]; next[u]=T.ch[v][c]; last[u]=T.val[next[u]]?next[u]:last[next[u]]; } } } void print(int j) { if(j) { sum[T.val[j]]++; //T.val[j]=0; //因为最后一个可能有自环,所以得把自环去掉 print(last[j]); } } void query(char *ss) { int l=strlen(ss),i,j=0,c; for(i=0; i<l; i++) { c=T.idx(ss[i]); j=T.ch[j][c]; if(T.val[j]) print(j); else if(last[j]) print(last[j]); } } int main() { int n; while(~sca(n)) { int i,l,k,flag=0; char s[53]; T.reset(); mem(sum,0); mem(next,0); mem(last,0); getchar(); for(i=1; i<=n; i++) { gets(ss[i]); T.insert(ss[i],i); } gets(str); getfail(); l=strlen(str); for(i=0,k=0; i<l; i++) { if(str[i]>='A'&&str[i]<='Z') { flag=1; s1[k++]=str[i]; } else if(flag) { s1[k]='\0'; if(strlen(s1)) query(s1); flag=0; k=0; } } if(flag) { s1[k]='\0'; if(strlen(s1)) query(s1); } for(i=1; i<=n; i++) if(sum[i]) printf("%s: %d\n",ss[i],sum[i]); } return 0; }