zoukankan      html  css  js  c++  java
  • HDU2896 病毒侵袭

    题目大意:给出若干病毒的特征码,不超过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("
    ");
           }
        }
        printf("total: %d
    ",bdwebs);
        return 0;
        }
  • 相关阅读:
    wpf 控件回车事件中调用tab实现方法
    C#中M的N次方显示
    新概念英语第三册单词
    新概念英语第二册单词
    手把手教你搭建一个vue项目
    Vuex里的module选项和移动端布局
    Vuex与axios的封装和调用
    Vue路由
    Vue脚手架的搭建和路由配置
    Vue全家桶之一Vue(基础知识篇)
  • 原文地址:https://www.cnblogs.com/hefenghhhh/p/5051334.html
Copyright © 2011-2022 走看看