• UVA11019KMP(二维矩阵匹配出现次数)


    题意:
        给你两个矩阵,一个大的一个小的,然后问你这个小矩阵在大的矩阵里出现了多少次?
    思路:
          说好了AC自动机的,我自己尝试写了个暴力的KMP竟然过了,AC自动机自己的模板还没写完,就暂时没用,说下KMP的解法吧,首先我们考虑如果是一维的情况,是不是就直接KMP裸题了,那么我们就想办法把二维降成一维,我用的是比较笨的方法就是把每一数列看成一个字母(每次比较的时候要比较一数列),求出next数组,然后在把大的那个串暴力拆成一些小串,宽度是他自己的宽度,长度是和小串长度一样,然后线性的去KMP就行了,一开始只是抱着试试的态度,毕竟时间复杂度最坏的情况太高,但是试的原因是这样的,在处理串匹配的时候时间往往并没有那么多,是可以根据概率算出来,就算是最笨的匹配方式,匹配失败就从头从新匹配,在随机数据的情况下也是很少的,并不能简单的(m+n*m)/2这样算,当时我的想法是如果这样超时了,我会去尝试把比较那个地方优化下,就是把两个串比较的那个地方,感觉string去处理可能会快一点(没有尝试),如果还超时那就只能把自己上午没写完的那个AC自动机模板写完(写了两天了,写的比较痛苦),然后在做了。不过没想到1A了。



    #include<stdio.h>
    #include<string.h>

    char stra[1002][1002];
    char strb[102][102];
    int next[102];

    bool jude(int a ,int b ,int n)
    {
        for(int i = 1 ;i<= n ;i ++)
        if(strb[i][a] != strb[i][b])
        return 0;
        return 1;
    }


    bool jude2(int a ,int b ,int I ,int k)
    {
        for(int i = 1 ;i <= k ;i ++)
        if(stra[i+I-1][a] != strb[i][b])
        return 0;
        return 1;
    }

    void GetNext(int n ,int m)
    {
        int j = 0 ,k = -1;
        next[0] = -1;
        while(j < m)
        {
            if(k == -1 || jude(j ,k ,n))
            next[++j] = ++k;
            else k = next[k];
        }
    }

    int KMP(int n ,int m ,int k ,int I)
    {
        int i ,j ,Ans = 0;
        for(i = j = 0 ;i < n ;)
        {
            if(jude2(i ,j ,I ,k))
            {
                if(j == m - 1) Ans ++;
                i ++ ,j ++;
            }
            else
            {
                j = next[j];
                if(j == -1)
                {
                    i ++ ,j = 0;
                }
            }
        }
        return Ans;
    }


    int main ()
    {
        int t ,n1 ,m1 ,n2 ,m2 ,i;
        scanf("%d" ,&t);
        while(t--)
        {
            scanf("%d %d" ,&n1 ,&m1);
            for(i = 1 ;i <= n1 ;i ++)
            scanf("%s" ,stra[i]);
            scanf("%d %d" ,&n2 ,&m2);
            for(i = 1 ;i <= n2 ;i ++)
            scanf("%s" ,&strb[i]);
            if(n2 > n1 || m2 > m1)
            {
                printf("0 ");
                continue;
            }
            GetNext(n2 ,m2);
            int Ans = 0;
            for(i = 1 ;i <= n1 - n2 + 1 ;i ++)
            {
                Ans += KMP(m1 ,m2 ,n2 ,i);
            }
            printf("%d " ,Ans);
        }
        return 0;
    }































  • 相关阅读:
    (十一)QPainter绘图, QPixmap,QImage,QPicture,QBitmap
    (十)事件,定时器
    (九)自定义控件
    (八)控件介绍,QLable
    (六)QDialog,QMessageBox,QFileDialog,QColorDialog颜色,QFontDialog字体
    (七)布局
    (五)qt资源文件
    (四)窗口mainwindow
    (三)信号与槽
    JMeter学习-011-JMeter 后置处理器实例之
  • 原文地址:https://www.cnblogs.com/csnd/p/12062536.html
Copyright © 2020-2023  润新知