您的位置:首页 > 其它

ZOJ 3430 Pizza schedule

2014-07-18 20:52 344 查看
题意:

给你一串编码后的单词和一篇文章  问  编码前文章中出现了几个单词

思路:

根据题意反编码  然后AC自动机跑一下

转化字符时候注意长度  因为可能转换出'\0'  所以转完后再求strlen会出错

注意  ZOJ的char默认是signed char  所以转码后要么存在unsigned char数组里  要么用int数组存  否则会错的!!  因为signed char无法表示128+的数字!!

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 51200
#define M 260

int n,m,tot,res;
struct node
{
int next[M];
int cnt,fail,vis;
void init()
{
memset(next,-1,sizeof(next));
fail=cnt=vis=0;
}
}nd
;
int qu
;
int head,tail;
char word
;
int code
;

void mf()
{
int i,j,idx,fa;
head=tail=0;
for(i=0;i<M;i++)
{
if(nd[0].next[i]!=-1)
qu[tail++]=nd[0].next[i];
}
while(head<tail)
{
fa=qu[head++];
for(i=0;i<M;i++)
{
if(nd[fa].next[i]!=-1)
{
qu[tail++]=nd[fa].next[i];
idx=nd[fa].fail;
while(idx>0&&nd[idx].next[i]==-1) idx=nd[idx].fail;
if(nd[idx].next[i]!=-1) idx=nd[idx].next[i];
nd[nd[fa].next[i]].fail=idx;
}
}
}
}

void fd(int len)
{
int i,idx,trvl;
for(i=idx=0;i<len;i++)
{
while(idx>0&&nd[idx].next[code[i]]==-1) idx=nd[idx].fail;
if(nd[idx].next[code[i]]!=-1)
{
trvl=idx=nd[idx].next[code[i]];
while(trvl>0&&nd[trvl].vis!=-1)
{
if(nd[trvl].cnt) res+=nd[trvl].cnt;
nd[trvl].vis=-1;
trvl=nd[trvl].fail;
}
}
}
}

int bin[N*10];
int change()
{
int i,j,k,len,tmp;
len=strlen(word);
for(i=k=0;i<len;i++)
{
if(word[i]=='=')
{
k-=2;
continue;
}
if(word[i]>='A'&&word[i]<='Z') tmp=word[i]-'A';
else if(word[i]>='a'&&word[i]<='z') tmp=word[i]-'a'+26;
else if(word[i]>='0'&&word[i]<='9') tmp=word[i]-'0'+52;
else if(word[i]=='+') tmp=62;
else if(word[i]=='/') tmp=63;
for(j=5;j>=0;j--)
{
if(tmp&(1<<j)) bin[k++]=1;
else bin[k++]=0;
}
}
for(i=len=0;i<k;i+=8)
{
for(j=i,tmp=0;j<i+8;j++) tmp=(tmp<<1)|bin[j];
code[len++]=tmp;
}
return len;
}

int main()
{
int i,len,j,idx;
while(~scanf("%d",&n))
{
tot=0;
nd[0].init();
for(i=1;i<=n;i++)
{
scanf("%s",word);
len=change();
for(j=idx=0;j<len;j++)
{
if(nd[idx].next[code[j]]==-1)
{
nd[idx].next[code[j]]=++tot;
nd[tot].init();
}
idx=nd[idx].next[code[j]];
}
nd[idx].cnt++;
}
mf();
scanf("%d",&m);
for(i=1;i<=m;i++)
{
res=0;
scanf("%s",word);
len=change();
fd(len);
printf("%d\n",res);
for(j=0;j<=tot;j++) nd[j].vis=0;
}
puts("");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: