题目大意:给出若干病毒的特征码,不超过500个。每个病毒的特征码长度在20~200之间。现在有若干网站的源代码,要检测网站的源代码中是否包含病毒。网站的个数不超过1000个,每个网站的源代码长度在7000~10000之间。已知如果包含病毒,最多包含三个病毒。输出每个含病毒网站包含的病毒的编号等信息,最后输出含病毒网站的个数。

裸的AC自动机题目。一开始把病毒的个数弄错了。因为宏定义比较多,一开始没有弄#define,全弄的数字。后边发现数字错了。改了一下,又改漏了一个。后边看别人的discuss,说是什么连续不重复匹配。结果完全是误导人。就是一个普通的字符串匹配。以后还是用宏来定义数组长度吧

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define MAXC 130
struct node
{
  int id,fail,nxt[MAXC];       
}trie[100010];
char word[202],web[10005];
int head,tail,tot=1,root=1,myq[100010],ans[502],bdk,n,m,bdwebs=0,res[10];
void insert(int r,char *s,int id)
{
   int len=strlen(s);
   for(int i=0;i<len;i++)
   {
      if(trie[r].nxt[s[i]-32]==0)
         trie[r].nxt[s[i]-32]=++tot;
       r=trie[r].nxt[s[i]-32];
   }     
   trie[r].id=id;
}
void build(int r)
{
  trie[r].fail=r;
  myq[tail++]=r;
  while(head<tail)
  {
    r=myq[head++];
    for(int i=0;i<MAXC;i++)
    {
      int ch=trie[r].nxt[i],failp;
      if(ch)
      {
        myq[tail++]=ch;
        for(failp=trie[r].fail;failp!=root&&trie[failp].nxt[i]==0;failp=trie[failp].fail);
        if(trie[failp].nxt[i]==0||trie[failp].nxt[i]==ch)
        trie[ch].fail=failp;
        else
        trie[ch].fail=trie[failp].nxt[i];
      }
    }
  }     
}
void query(int r,char *s)
{
     int len=strlen(s),tempfail;
     for(int i=0;i<len;i++)
     {
        while(trie[r].nxt[s[i]-32]==0&&r!=root)
          r=trie[r].fail;  
         r=trie[r].nxt[s[i]-32];
         if(r==0)r=root;
         for(tempfail=r;tempfail!=root;tempfail=trie[tempfail].fail)
         {
            if(ans[trie[tempfail].id])break;                                           
            if(trie[tempfail].id>0)
              {ans[trie[tempfail].id]=1;
              }
         }
     }
}
int main()
{
    root=1;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
      scanf("%s",word);
      insert(root,word,i+1);
    }
    build(root);
    scanf("%d",&m);
    for(int i=0;i<m;i++)
    {
       scanf("%s",web);
       memset(ans,0,sizeof ans);
       bdk=0;
       query(root,web);
       for(int k=0;k<502;k++)
       if(ans[k])res[bdk++]=k;
       if(bdk>0)
       {
         bdwebs++;
         printf("web %d:",i+1);
         for(int k=0;k<bdk;k++)
         printf(" %d",res[k]);
         printf("\n");
       }
    }
    printf("total: %d\n",bdwebs);
    return 0;
    }

 

相关文章:

  • 2021-10-22
  • 2021-06-29
  • 2021-08-08
  • 2022-03-07
  • 2022-02-22
  • 2022-12-23
  • 2022-01-15
猜你喜欢
  • 2021-05-24
  • 2021-07-10
  • 2022-01-31
  • 2021-06-06
  • 2022-12-23
  • 2021-05-30
  • 2021-12-30
相关资源
相似解决方案