zoj 3430

来源:互联网 发布:数控加工螺纹的编程 编辑:程序博客网 时间:2024/06/06 00:51

这个题解码部分比较繁琐,剩下就是裸AC自动机了。

代码能力不强竟然调试了一天。。。。

#include<cstdio>#include<cstring>#include<queue>#include<cstdlib>const int kind=256;using namespace std;char b[3000];    //a模式串,b为匹配串bool vis[550];int bb[3000];int mp[200];int length;struct trie{struct trie * fail,*next[kind];int count;int id;trie(){fail=NULL;count=0;memset(next,NULL,sizeof(next));}};struct trie * root;void insert(int* str,int len,int id){int i,tem;struct trie *p,*q;p=root;for(i=0;i<len;i++){tem=str[i];if(p->next[tem]==NULL){q=(struct trie*)calloc(1,sizeof(struct trie));q->count=0;q->fail=NULL;memset(q->next,NULL,sizeof(q->next));p->next[tem]=q;}p=p->next[tem];}p->count+=1;p->id=id;}void buildac(){int i;struct trie *p,*tem;queue<struct trie *>q;root->fail=NULL;q.push(root);while(!q.empty()){tem=q.front();q.pop();for(i=0;i<kind;i++){if(tem->next[i]!=NULL){if(tem==root)tem->next[i]->fail=root;else{p=tem->fail;while(p!=NULL){if(p->next[i]!=NULL){tem->next[i]->fail=p->next[i];break;}p=p->fail;}if(p==NULL)tem->next[i]->fail=root;}q.push(tem->next[i]);}}}}int query(int *str,int len){int i,tem,result=0;struct trie* tmp=root,*p;for(i=0;i<len;i++){tem=str[i];while(tmp->next[tem]==NULL && tmp!=root)tmp=tmp->fail;tmp=tmp->next[tem];if(tmp==NULL)tmp=root;p=tmp;while(p!=root && vis[p->id]==0){            //每到一个位置就加上p->count,以及以他的后缀为前缀的单词if(p->id!=0)vis[p->id]=1;                       //这里我WA了一天result+=p->count;p=p->fail;}}return result;}void decode(){int i,j,len;len=strlen(b);if(b[len-1]=='=' && b[len-2]=='=')length=((len-2)*6-4)/8;else if(b[len-1]=='=' && b[len-2]!='=')length=((len-1)*6-2)/8;else if(b[len-1]!='=' && b[len-2]!='=')length=len*6/8;for(i=0,j=0;j<len-4;i+=3,j+=4){bb[i]=(mp[b[j]]<<2)+(mp[b[j+1]]>>4);bb[i+1]=((mp[b[j+1]]&15)<<4)+(mp[b[j+2]]>>2);bb[i+2]=((mp[b[j+2]]&3)<<6)+(mp[b[j+3]]);}bb[i]=(mp[b[j]]<<2)+(mp[b[j+1]]>>4);if(b[len-2]!='=')bb[i+1]=((mp[b[j+1]]&15)<<4)+(mp[b[j+2]]>>2);if(b[len-1]!='=')bb[i+2]=((mp[b[j+2]]&3)<<6)+(mp[b[j+3]]);}void init(){int i;for(i='A';i<='Z';i++)mp[i]=i-'A';for(i='a';i<='z';i++)mp[i]=i-'a'+26;for(i='0';i<='9';i++)mp[i]=i-'0'+52;mp['+']=62;mp['/']=63;}void destroy(struct trie * r){for(int i=0;i<kind;i++)if(r->next[i]!=NULL)destroy(r->next[i]);delete(r);}int main(){//freopen("a.txt","r",stdin);//freopen("c.txt","w",stdout);int t,T,n,m,i,j,sum;init();while(scanf("%d",&n)!=EOF){root=(struct trie*)calloc(1,sizeof(struct trie));root->fail=NULL;root->count=0;memset(root->next,NULL,sizeof(root->next));for(i=1;i<=n;i++){scanf("%s",b);memset(bb,0,sizeof(bb));decode();//printf("*****");//for(int k=0;k<length;k++)//printf("%d ",bb[k]);//printf("\n");insert(bb,length,i);}buildac();scanf("%d",&m);for(i=1;i<=m;i++){scanf("%s",b);memset(bb,0,sizeof(bb));decode();//printf("*****");//for(int k=0;k<length;k++)//printf("%d ",bb[k]);//printf("\n");memset(vis,0,sizeof(vis));printf("%d\n",query(bb,length));}printf("\n");destroy(root);         //这里释放内存空间降低内存使用}return 0;}

写了个暴跑程序对拍才看出哪错了。。。
 

 

原创粉丝点击