zoukankan      html  css  js  c++  java
  • Uva11019 Matrix Matcher-AC自动机二维匹配

    一看题冒出各种奇奇怪怪不可做的想法

    其实做法也很简单

    把每行作为模式串插入AC自动机

    再拿小矩阵每行去匹配

    在匹配成功之后需要搞点事情

    匹配成功后给对应的左上角的计数器加一

    最后统计一遍即可

    代码里有一些特别奇怪的东西,比如拿邻接表存相同的行什么的(要不会MLE)

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cctype>
    #include<cstdio>
    #include<queue>
    using namespace std;
    
    const int MAXN = 1002, MAXX = 102, MAXNnode = 1000002;
    
    struct Node{
        int tag, fail, nxt[26];
        inline void init(){tag = fail = 0; memset(nxt, 0, sizeof(nxt));}
    }t[MAXNnode];
    int T, n, m, n2, m2, ptr, Root;
    int cnt[MAXN][MAXN], head[MAXX];
    char txt[MAXN][MAXN], str[MAXX][MAXX];
    queue<int> q;
    
    inline void Insert(int No) {
        int cur = Root;
        for(int i = 1; i <= m2; ++i) {
            register int x = str[No][i] - 'a';
            if(!t[cur].nxt[x]) {
                t[cur].nxt[x] = ++ptr;
                t[ptr].init();
            }
            cur = t[cur].nxt[x];
        }
        if(t[cur].tag) head[No] = t[cur].tag;
        t[cur].tag = No;
        return;
    }
    inline void getfail() {
        t[Root].fail = 0;
        for(int i = 0; i < 26; ++i) 
            if(t[Root].nxt[i]) {
                t[t[Root].nxt[i]].fail = Root;
                q.push(t[Root].nxt[i]);
            } else t[Root].nxt[i] = Root;
        while(!q.empty()) {
            int cur = q.front(); q.pop();
            for(int i = 0; i < 26; ++i) {
                register int son = t[cur].nxt[i];
                if(!son) {
                    t[cur].nxt[i] = t[t[cur].fail].nxt[i];
                    continue;
                }
                t[son].fail = t[t[cur].fail].nxt[i];
                if(t[t[son].fail].tag) t[son].tag = t[t[son].fail].tag;
                q.push(son);
            }
        }
        return;
    }
    inline void update(int x, int y, int z) {
        if(x >= z) ++cnt[x - z + 1][y - m2 + 1];
        while(head[z]) {
            z = head[z];
            if(x >= z) ++cnt[x - z + 1][y - m2 + 1];
        }
        return;
    }
    inline void acfind() {
        int cur = Root;
        for(int i = 1; i <= n; ++i) {
            cur = Root;
            for(int j = 1; j <= m; ++j) {
                cur = t[cur].nxt[txt[i][j] - 'a'];
                if(t[cur].tag) 
                    update(i, j, t[cur].tag);
            }
        }
        return;
    }
    inline void resetall() {
        ptr = 0;
        memset(t + Root, 0, sizeof(Node));
        memset(head, 0, sizeof(head));
        for(int i = 0; i <= n; ++i) 
            for(int j = 0; j <= m; ++j) 
                cnt[i][j] = 0;
        return;
    }
    inline int rd() {
        register int x = 0;
        register char c = getchar();
        while(!isdigit(c)) c = getchar();
        while(isdigit(c)) {
            x = x * 10 + (c ^ 48);
            c = getchar();
        }
        return x;
    }
    
    int main() {
        T = rd();
        while(T--) {
            scanf("%d%d", &n, &m);
            for(int i = 1; i <= n; ++i) scanf("%s", txt[i] + 1);
            scanf("%d%d", &n2, &m2);
            for(int i = 1; i <= n2; ++i) {
                scanf("%s", str[i] + 1);
                Insert(i);
            }
            getfail();
            acfind();
            int ans = 0;
            for(int i = 1; i <= n; ++i) {
                for(int j = 1; j <= m; ++j) {
                    if(cnt[i][j] >= n2) ++ans;
                }
            }
            printf("%d
    ", ans);
            resetall();
        }
        return 0;
    }
    
    禁止诸如开发者知识库/布布扣/码迷/学步园/马开东等 copy 他人博文乃至博客的网站转载 ,用户转载请注明出处:https://www.cnblogs.com/xcysblog/
  • 相关阅读:
    直接从国家统计局上找数据,并分析人口数据变化,做成可视化图
    Python爬虫:爬取某日头条某瓜视频,有/无水印两种方法
    教你如何爬取美团网数据,就是那么的简单
    你所在的城市空气质量如何?用Python可视化分析空气质量
    Python爬取股票数据,让你感受一下什么是一秒钟两千条数据
    小伙用Python制作一个小游戏,结果6秒就结束,怎么难玩?
    Python数据可视化:一张很漂亮的商业图
    反射练习题1
    字符串格式化总结补充与有序字典
    反射应用实例:importlib模块
  • 原文地址:https://www.cnblogs.com/xcysblog/p/9314853.html
Copyright © 2011-2022 走看看