HDU 2896 病毒侵袭 AC自己主动机题解

HDU 2896 病毒侵袭 AC自己主动机题解

大家好,又见面了,我是全栈君。

本题是在text里面查找key word的增强版。由于这里有多个text。

那么就不能够简单把Trie的叶子标志记录改动成-1进行加速了,能够使用其它技术。我直接使用个vis数组记录已经訪问过的节点,达到加速效果,速度还算挺快的。

只是看discuss里面有人直接使用Trie,做出了140ms的速度,并且他的程序严格来说并不对。可见本题的数据非常水啊。Trie的时间效率肯定比AC自己主动机低,可是在数据非常水的特殊情况下。Trie的速度也能够非常快的。

注意两个细节:

1 病毒也须要安装顺序输出,不小心就遗漏了。这里害我错了几次。

2 还有就是题目的字符不确定是多少。使用33-94范围的字符測试答案正确的。

#include <stdio.h>
#include <string.h>
#include <queue>
#include <set>
#include <algorithm>
using namespace std;
const int MAX_N = 501;
const int MAX_WORD = 201;
const int MAX_M = 1001;
const int MAX_TXT = 10001;
const int MAX_V = 3;
const int ARR_SIZE = 94;
char virus[MAX_WORD], web[MAX_TXT];
int webNum[MAX_V];
int M, N;

inline int getIndex(char ch) { return ch - 33; }

struct Node
{
    int n, num, id;
    Node *fail;
    Node *arr[ARR_SIZE];
};

void clearNode(Node *rt)
{
    rt->n = 0;
    rt->num = 0;
    rt->id = 0;
    rt->fail = NULL;
    for (int i = 0; i < ARR_SIZE; i++)
    {
        rt->arr[i] = NULL;
    }
}

Node gPool[MAX_N*MAX_WORD], *Trie;
int gPoolID;
bool vis[MAX_N*MAX_WORD];    //怎么老是忘记使用visited技术的?

void insertTrie(char *virus, int num)
{
    Node *pCrawl = Trie;
    for (; *virus; virus++)
    {
        int id = getIndex(*virus);
        if (!pCrawl->arr[id])
        {
            pCrawl->arr[id] = &gPool[gPoolID++];
            clearNode(pCrawl->arr[id]);
            pCrawl->arr[id]->id = gPoolID-1;
        }
        pCrawl = pCrawl->arr[id];
    }
    pCrawl->n++;
    pCrawl->num = num;
}

void buildFail()
{
    queue<Node *> qu;
    qu.push(Trie);
    while (!qu.empty())
    {
        Node *p = qu.front(); qu.pop();
        for (int i = 0; i < ARR_SIZE; i++)
        {
            if (!p->arr[i]) continue;
            p->arr[i]->fail = Trie;
            Node *fail = p->fail;
            while (fail)
            {
                if (fail->arr[i])
                {
                    p->arr[i]->fail = fail->arr[i];
                    break;
                }
                fail = fail->fail;
            }
            qu.push(p->arr[i]);
        }
    }
}

int searchVirus(char *web)
{
    int n = 0;
    Node *pCrawl = Trie;
    memset(vis, 0, sizeof(bool)*(gPoolID+1));
    for (; *web; web++)
    {
        int i = getIndex(*web);
        while (!pCrawl->arr[i] && pCrawl != Trie) pCrawl = pCrawl->fail;
        if (pCrawl->arr[i])
        {
            pCrawl = pCrawl->arr[i];
            Node *p = pCrawl;
            while (p && !vis[p->id])//使用vis比直接检查数组值快捷方便
            {
                if (p->n) webNum[n++] = p->num;
                vis[p->id] = true;
                p = p->fail;
            }
            if (n == MAX_V) break;    //At most MAX_V virus one web
        }        
    }
    return n;
}

int main()
{
    Trie = &gPool[0];
    while (scanf("%d", &N) != EOF)
    {
        gPoolID = 1;
        clearNode(Trie);
        getchar();
        for (int i = 1; i <= N; i++)
        {
            gets(virus);
            insertTrie(virus, i);
        }
        buildFail();

        scanf("%d", &M);
        getchar();
        int cnt = 0;
        for (int i = 1; i <= M; i++)
        {
            gets(web);
            int n = searchVirus(web);
            if (n)
            {
                cnt++;
                printf("web %d:", i);

                sort(webNum, webNum + n);//Watch out: order!
                for (int j = 0; j < n; j++)
                {
                    printf(" %d", webNum[j]);
                }
                putchar('\n');
            }
        }
        printf("total: %d\n", cnt);
    }
    return 0;
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/116130.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 良心推荐,我珍藏的一些Chrome插件[通俗易懂]

    良心推荐,我珍藏的一些Chrome插件[通俗易懂]上次搬家的时候,发了一个朋友圈,附带的照片中不小心暴露了自己的Chrome浏览器插件之多,于是就有小伙伴评论说分享一下我觉得还不错的浏览器插件。我下面就把我日常工作和学习中经常用到的一些Chrome浏览器插件分享给大家,随便一个都能提高你的“生活品质”和工作效率。MarkdownHereMarkdownHere可以让你更愉快的写邮件,由于支持Markdown直接转电子邮…

    2022年6月10日
    27
  • dz论坛数据库php网址,discuz论坛更换域名,搬家步骤

    dz论坛数据库php网址,discuz论坛更换域名,搬家步骤搬家步骤具体如下:1、打包数据库文件保存到本地。2、打包网站根目录所有程序(discuz)保存到本地。3、上传网站程序包和数据库包到新的空间,将数据库上传到新的服务器中。4、找到config\config_global.php文件,修改以下3处内容:$_config[‘db‘][‘1‘][‘dbuser‘]=‘数据库用户名‘;$_config[‘db‘][‘1‘][‘dbpw‘]=‘数…

    2022年7月25日
    11
  • oracle 优化or 更换in、exists、union all几个字眼,测试没有问题!

    oracle 优化or 更换in、exists、union all几个字眼,测试没有问题!

    2022年1月1日
    52
  • Pytest(2)使用和调用方法

    Pytest(2)使用和调用方法Pytest执行用例规则Pytest在命令行中支持多种方式来运行和选择测试用例1.对某个目录下所有的用例pytest2.对模块中进行测试pytesttest_mod.py3.对文件夹进行

    2022年7月30日
    8
  • 学生信息管理系统的用例图和图书管理系统系统分析及用例图[通俗易懂]

    学生信息管理系统的用例图和图书管理系统系统分析及用例图[通俗易懂]练习一:请画出学生信息管理系统的用例图“学生信息管理系统”功能性需求包括以下内容:      (1)系统管理员登录后可以对班级的基本信息进行增加、删除、修改、查询等操作。学校领导登录后可以对班级基本信息进行查询操作。      (2)教师登录后可以对学生的考试成绩进行录入、删除、修改、查询等操作。学生登录后可以对考试成绩进行查询操作。      (3)学生登录后可以了解所有

    2022年5月26日
    105
  • Oracle创建表空间、创建用户、授予权限、锁定、解锁以及删除用户等[通俗易懂]

    Oracle创建表空间、创建用户、授予权限、锁定、解锁以及删除用户等[通俗易懂]Oracle创建表空间、创建用户、授予权限以及删除用户等–创建表空间CREATETABLESPACEcaiylDATAFILE’D:\Oracle\app\caiyl\oradata\orcl\caiyl_space.dbf’size500mAUTOEXTENDONNEXT200MMAXSIZE20480MEXTENTMANAGEMENTLOCAL;

    2022年7月16日
    12

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号