hdu 3336

题意:输入一个字符串求每个前缀在串中出现的次数和

sol:只要稍微理解下next 数组的含义就知道只要把每个有意义的next值得个数加起来即可

PS:网上有dp解法orz,dp[i]表示以i为前缀串结尾的前缀串的总和,方程很容易写出

//字符串上KMP(水)
//从前向后扫,失配函数的位置就是一个前缀的位置减1
//加起来就好了
// by acvc
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAX = ;
const int MOD = ;
char str[MAX];
int next[MAX],vis[MAX];
int main()
{
    int cas,n;
    scanf("%d",&cas);
    while(cas--)
    {
        scanf("%d %s",&n,str);
        next[]=next[]=;
        for(int i=;i<n;i++)
        {
            int j=next[i];
            while(j&&str[i]!=str[j]) j=next[j];
            if(str[i]==str[j])
            next[i+]=j+;
            else next[i+]=;
        }
        int ans=,cnt=;
        for(int i=;i<n;i++)
        {
            if(next[i])
            {
            //    cnt++;
                ans=(ans+)%MOD;
            }
            else
            ans=(ans+)%MOD;
        }
        if(next[n]) ans=(ans+)%MOD;
        printf("%d\n",(ans)%MOD);
    }
    return ;

}

hdu 1358

题意:给出一个字符串求出每个前缀的最小周期

sol:next数组理解题目稍微想想就知道t=(len-next[len])

//kmp小深入题目
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAX = +;
char str[MAX]; int next[MAX]; //失配函数
int main()
{
    int n,cnt=;
    while(scanf("%d",&n)>)
    {
        scanf("%s",str);
        next[]=next[]=;
        for(int i=;i<n;i++)
        {
            int j=next[i];
            while(j&&str[i]!=str[j]) j=next[j];
            if(str[i]==str[j]) next[i]=j+;
            else next[i]=;
        }
        printf("Test case #%d\n",++cnt);
        for(int i=;i<=n;i++)
        {
            if(next[i]&&i%(i-next[i])==)
            printf("%d %d\n",i,i%(i-next[i]));
        }
    }
    return ;

}

hdu1711

题意:给出两个数组,求出b在a中最先匹配的位置

sol:KMP裸题

 1 //裸题
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<algorithm>
 5 using namespace std;
 6 const int MAX = 1e6+;
 7 int next[MAX];
 8 int a[MAX],b[MAX];
 9 int main()
 {
     int cas,n,m;
     scanf("%d",&cas);
     while(cas--)
     {
         scanf("%d %d",&n,&m);
         for(int i=;i<n;i++) scanf("%d",&a[i]);
         for(int j=;j<m;j++) scanf("%d",&b[j]);
         next[]=next[]=;
         for(int i=;i<m;i++)
         {
             int j=next[i];
             while(j&&b[i]!=b[j]) j=next[j];
             if(b[i]==b[j]) next[i+]=j+;
             else next[i+]=;
         }
         int cur=,flag=;
         for(int i=;i<n;i++)
         {
             while(cur&&a[i]!=b[cur]) cur=next[cur];
             if(a[i]==b[cur]) cur++;
             if(cur==m)
             {
                 flag=;
                 printf("%d\n",i-cur+);
                 break;
             }
         }
         if(!flag) printf("-1\n");
     }
     return ;

41 }

hdu2087

题意:给定串1和串2求串2在串1中出现的顺序

sol;裸KMP从前向后扫一遍kmp就好了

 1 #include<cstring>
 2 #include<algorithm>
 3 #include<cstdio>
 4 using namespace std;
 5 const int MAX = +;
 6 char str1[MAX],str2[MAX];
 7 int next[MAX];
 8 int main()
 9 {
     while(scanf("%s",str1)&&strcmp(str1,"#"))
     {
         int ans=;
         scanf("%s",str2);
         int n=strlen(str2); next[]=next[]=;
         for(int i=;i<n;i++)
         {
             int j=next[i];
             while(j&&str2[i]!=str2[j]) j=next[j];
             if(str2[i]==str2[j]) next[i+]=j+;
             else next[i+]=;
         }
         int len=strlen(str1); int j=;
         for(int i=;i<len;i++)
         {
             while(j&&str1[i]!=str2[j]) j=next[j];
             if(str1[i]==str2[j]) j++;
             if(j==n)
             {
                 ans++;
                 j=;
             }
         }
         printf("%d\n",ans);
     }
     return ;

36 }

poj2406

题意:给定一个串求出串的最小周期

los:失配函数裸题啊

 1 //kmp-shui
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cstdio>
 5 using namespace std;
 6 const int MAX = 1e6+;
 7 char str[MAX]; int next[MAX];
 8 int main()
 9 {
     int ans;
     while()
     {
         gets(str); if(!strcmp(str,".")) break;
         int n=strlen(str); next[]=next[]=;
         for(int i=;i<n;i++)
         {
             int j=next[i];
             while(j&&str[i]!=str[j]) j=next[j];
             if(str[i]==str[j]) next[i+]=j+;
             else next[i+]=;
         }
         if(n%(n-next[n])==)
         printf("%d\n",n/(n-next[n]));
         else printf("1\n");
     }
     return ;

27 }

poj 2752

题意:给定一个串求出满足既是前缀又是后缀的串的起始位置

sol:又是一发next数组加深题目,很明显next数组指向的是最长的一个前缀串,所以最后一个指针指向的next就是一个最长前缀

之后从这个最长前缀末尾开始下一个指针又是前缀的最长前缀,而后缀和前缀相同,所以这个是第二长的前缀,只要递归结束即可

1 //kmp题目shui by acvc

 2 //kmp每次都是求的最长的前缀
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cstdio>
 6 #include<vector>
 7 using namespace std;
 8 const int MAX = +;
 9 int next[MAX];
 char str[MAX];
 vector<int> s;
 int main()
 {
     while(scanf("%s",str)!=EOF)
     {
         s.clear();
         int n=strlen(str); next[]=,next[]=;
         for(int i=;i<n;i++)
         {
             int j=next[i];
             while(j&&str[i]!=str[j]) j=next[j];
             if(str[i]==str[j]) next[i+]=j+;
             else next[i+]=;
         }
         //for(int i=0;i<=n;i++) printf("%d ",next[i]);
     //    printf("\n");
         int j=strlen(str);
         while(j)
         {
             s.push_back(j);
             j=next[j];
         }
         for(int i=s.size()-;i>=;i--)
         {
             if(i==s.size()-) printf("%d",s[i]);
             else printf(" %d",s[i]);
         }
         printf("\n");
     }
     return ;
 }

poj 2185

题意:输入一个矩阵由字符组成,求出矩阵的最小组成单位。

sol:网上好多代码都是错的,第一次学被误解了,今天重新修改这道题,其实找出每一行的周期串记录下个数,最后等于行数的肯定就是最小的宽。

求高直接公式就好了,

 1 /************************
 2 *    zhuyuqi            *
 3 *    QQ:1113865149      *
 4 *    worfzyq@gmail.com  *
 5 *************************/
 6 #include <cstdio>
 7 #include <cstring>
 8 #include <algorithm>
 9 #include <cmath>
 #include <vector>
 #include <list>
 #include <queue>
 using namespace std;
 const int MAX = 1e4+;
 const int inf = 0x3f3f3f3f;
 char str[MAX][];
 int next[MAX],ML[MAX],vis[MAX];
 int main()
 {
 
     int n,m; int L,R;
     while(scanf("%d %d",&n,&m)==) {
         for(int i=;i<=n;i++) {
             scanf("%s",str[i]+);
         }
        // for(int i=1;i<=n;i++) printf("%s\n",str[i]+1);
         memset(ML,,sizeof(ML));
         if(m>) {
             for(int i=;i<=n;i++) {
                 next[]=; int j=; memset(vis,,sizeof(vis));
                 for(int k=;k<=m;k++) {
                     while(j&&str[i][k]!=str[i][j+]) j=next[j];
                     if(str[i][k]==str[i][j+]) j++;
                     next[k]=j;
                 }
                 int x=m;
             //    for(int k=1;k<=m;k++) printf("%d ",next[k]); printf("\n");
                 while(x) {
                    // if(x==1) break;
                     if(!vis[m-next[x]])
                     ML[m-next[x]]++; x=next[x];  vis[x-next[x]]=;
                 }
             }
             for(int i=;i<=m;i++) if(ML[i]==n) {
                 L=i; break;
             }
         } else L=;
         next[]=; int j=;
         for(int i=;i<=n;i++) {
             while(j&&strcmp(str[i]+,str[j+]+)) j=next[j];
 //            printf("%d %d\n",i,j+1);
             if(!strcmp(str[i]+,str[j+]+)) j++;
           //  printf("%d %d\n",next[i],j);
             next[i]=j;
         }
         //printf("%d %d\n",L,n-next[n]);
         printf("%d\n",(n-next[n])*L);
 
     }
 
     return ;
 }

hdu poj KMP简单题目总结的更多相关文章

  1. Least Common Multiple (HDU - 1019) 【简单数论】【LCM】【欧几里得辗转相除法】

    Least Common Multiple (HDU - 1019) [简单数论][LCM][欧几里得辗转相除法] 标签: 入门讲座题解 数论 题目描述 The least common multip ...

  2. 七夕节 (HDU - 1215) 【简单数论】【找因数】

    七夕节 (HDU - 1215) [简单数论][找因数] 标签: 入门讲座题解 数论 题目描述 七夕节那天,月老来到数字王国,他在城门上贴了一张告示,并且和数字王国的人们说:"你们想知道你们 ...

  3. Cyclic Nacklace HDU 3746 KMP 循环节

    Cyclic Nacklace HDU 3746 KMP 循环节 题意 给你一个字符串,然后在字符串的末尾添加最少的字符,使这个字符串经过首尾链接后是一个由循环节构成的环. 解题思路 next[len ...

  4. SDUT-2772_数据结构实验之串一:KMP简单应用

    数据结构实验之串一:KMP简单应用 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 给定两个字符串string1和str ...

  5. hdu 1686 KMP模板

    // hdu 1686 KMP模板 // 没啥好说的,KMP裸题,这里是MP模板 #include <cstdio> #include <iostream> #include ...

  6. HDU 2085 核反应堆 --- 简单递推

    HDU 2085 核反应堆 /* HDU 2085 核反应堆 --- 简单递推 */ #include <cstdio> ; long long a[N], b[N]; //a表示高能质点 ...

  7. SDUT 2772 数据结构实验之串一:KMP简单应用

    数据结构实验之串一:KMP简单应用 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Problem Description 给定两个 ...

  8. hdu 4300(kmp)

    题意:说实话这个题的题意还真的挺难懂的,我开始看了好久都没看懂,后来百度了下题意才弄懂了,这题的意思就是首先有一个字母的转换表,就是输入的第一行的字符串,就是'a'转成第一个字母,'b'转成转换表的第 ...

  9. SDUT OJ 数据结构实验之串一:KMP简单应用 && 浅谈对看毛片算法的理解

    数据结构实验之串一:KMP简单应用 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Discuss Problem Descr ...

随机推荐

  1. bzoj 1047: [HAOI2007]理想的正方形【单调队列】

    没有复杂结构甚至不长但是写起来就很想死的代码类型 原理非常简单,就是用先用单调队列处理出mn1[i][j]表示i行的j到j+k-1列的最小值,mx1[i][j]表示i行的j到j+k-1列的最大值 然后 ...

  2. bzoj 1914: [Usaco2010 OPen]Triangle Counting 数三角形【叉积+极角排序+瞎搞】

    参考:https://blog.csdn.net/u012288458/article/details/50830498 有点神啊 正难则反,考虑计算不符合要求的三角形.具体方法是枚举每个点,把这个点 ...

  3. bzoj2679: [Usaco2012 Open]Balanced Cow Subsets(折半搜索)

    2679: [Usaco2012 Open]Balanced Cow Subsets Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 462  Solv ...

  4. Asp.Net 开发实战技术

    1.什么是WMI技术 WMI是一项核心的Windows管理技术,WMI作为一种规范和基础结构,通过它可以访问.配置.管理和监视几乎所有的Windows资源,比如用户可以在远程计算机器上启动一个进程:设 ...

  5. 大数高精度加减乘除 51nod 1005 大数加法

    1005 大数加法 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题  收藏  关注 给出2个大整数A,B,计算A+B的结果. Input 第1行:大数A 第2行:大数B ...

  6. 【Python精华】100个Python练手小程序

    100个Python练手小程序,学习python的很好的资料,覆盖了python中的每一部分,可以边学习边练习,更容易掌握python. [程序1] 题目:有1.2.3.4个数字,能组成多少个互不相同 ...

  7. 专题八:P2P编程

    引言: 前面的介绍专题中有朋友向我留言说介绍下关于P2P相关的内容的,首先本人对于C#网络编程也不是什么大牛,因为能力的关系,也只能把自己的一些学习过程和自己的一些学习过程中的理解和大家分享下的,下面 ...

  8. Knockout应用开发指南(完整版) 目录索引(转)

    使用Knockout有一段时间了(确切的说从MIX11大会宣传该JavaScript类库以来,我们就在使用,目前已经在正式的asp.net MVC项目中使用),Knockout使用js代码达到双向绑定 ...

  9. go 语言开发环境的安装与配置

    go 语言开发环境的安装与配置 编辑器选择 一直以来都是用sublime,但是听说sublime对于golang的插件支持并不是特别完善,并且VS Code只要在自身所带的扩展商店里安装go插件就可以 ...

  10. acm练习-day1

    描述现在,有一行括号序列,请你检查这行括号是否配对.输入第一行输入一个数N(0<N<=100),表示有N组测试数据.后面的N行输入多组输入数据,每组输入数据都是一个字符串S(S的长度小于1 ...