您的位置:首页 > 其它

zoj 3228 Searching the String

2013-03-29 16:57 274 查看
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3441

trie 这是一个自动机的题 不过trie就可以解决

先对长串进行处理 由于后面出现的字符串最长为6 所以以长串每个位置的字符为起点用长度1-6的子串进行建树

建树时 对树里面的节点要维护 到此节点位置的字符串在原串中出现的位置(多个) 并更新出现的个数和不允许重叠的个数

然后输入短串时就好处理了

代码:

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <queue>
#include <stack>

using namespace std;

const int N=1005;
const int M=100010;
const int K=26;
int I;
struct node
{
int v,next;
}edge[M*6];
struct nodeTrie
{
int next[K];
int head;
int len;
void initialize()
{
head=-1;
len=0;
memset(next,-1,sizeof(next));
}
}trie[M*6];
int cnt,root;
char s[10];
char ls[M];
int num[M*6];
int getNewNode()
{
++cnt;
trie[cnt].initialize();
return cnt;
}
void addWord(int p,int l,int r)
{
for(int i=l;i<r;++i)
{
if(trie[p].next[ls[i]-'a']==-1)
trie[p].next[ls[i]-'a']=getNewNode();
p=trie[p].next[ls[i]-'a'];
num[I]=1;
++trie[p].len;
edge[I].v=l;
edge[I].next=trie[p].head;
trie[p].head=I;
for(int t=trie[p].head;t!=-1;t=edge[t].next)
if(edge[t].v+(i-l+1)<=l)
{num[I]=num[t]+1;break;}
++I;
}
}
void init(int n)
{
cnt=-1;I=0;
root=getNewNode();
for(int i=0;i<n;++i)
addWord(root,i,min(i+6,n));
}
int searchWord(int p,char *s)
{
for(int i=0;s[i]!='\0';++i)
{
if(trie[p].next[s[i]-'a']==-1)
return 0;
p=trie[p].next[s[i]-'a'];
}
return p;
}
int findNum(char *s,int flag)
{
int p=searchWord(root,s);
if(p==0) return 0;
if(flag==0)
return trie[p].len;
if(trie[p].len<=1)
return trie[p].len;
return num[trie[p].head];
}
int main()
{
//freopen("data.in","r",stdin);
int ca=0;
while(gets(ls))
{
++ca;
init(strlen(ls));
int n;
scanf("%d",&n);
printf("Case %d\n",ca);
while(n--)
{
int flag;
scanf("%d ",&flag);
gets(s);
printf("%d\n",findNum(s,flag));
}
printf("\n");
scanf(" ");
}
return 0;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: