1、传送门:http://begin.lydsy.com/JudgeOnline/problem.php?id=2725

  题目大意:找一个串在另一个串中出现的次数

  题解:kmp(纯裸题)

  

 #include<iostream>
#include<cstring>
#include<cstdio>
#define maxn 1000100
int n,fix,ans,i,lens,lent;
char s[maxn],t[maxn];
int next[maxn];
void getnext()
{
fix=;
for (i=; i<=lent; i++)
{
while(fix && t[fix+]!=t[i]) fix=next[fix];
if (t[fix+]==t[i]) fix++;
next[i]=fix;
}
}
int KMP()
{
int count;
fix=; count=;
for (int i=; i<=lens; i++)
{
while (fix && t[fix+]!=s[i]) fix=next[fix];
if (t[fix+]==s[i]) fix++;
if (fix==lent)
{
count++;
fix=next[fix];
}
}
return count;
}
int main()
{
int z;
scanf("%d",&z);
for (int zz=; zz<=z; zz++)
{
scanf("%s",t+);
scanf("%s",s+);
lens=strlen(s+);
lent=strlen(t+);
memset(next,,sizeof(next));
getnext();
ans=KMP();
printf("%d\n",ans);
}
return ;
}

  

2、传送门:http://begin.lydsy.com/JudgeOnline/problem.php?id=2732

  题目大意:给你一个字符串,让你求出最大重复周期(最大周期不和本身重合)

  题解:kmp或者扩展kmp(但我并未用这种方法),我用的是kmp,但是一直WA,原来是求next数组把while写成了if(手抖毁一生)。

     好吧,写题解了:用kmp求出next数组,然后在去递归next[n],因为j=next[next[n]]一直next下去直到其的next为0就ans+=n-j;

     这就可以求出不和母串一样的最大重复周期,但是这又有一个问题你在求j时要递归时间就有可能为n^2的所以在每次递归时改变next的值就好了(详见代码);

  

 #include<iostream>
#include<cstring>
#include<cstdio>
#define inf 0x7ffffff
#define maxn 1000100
char s[maxn];
int nnext[maxn];
int n,i,j,fix;
long long ans;
using namespace std;
int main()
{
scanf("%d",&n);
scanf("%s",s+);
fix=;
for (int i=; i<=n; i++)
{
while (fix && s[fix+]!=s[i]) fix=nnext[fix];
if (s[fix+]==s[i]) fix++;
nnext[i]=fix;
}
ans=;
for (int i=; i<=n; i++)
{
int j=i;
if (!nnext[j]) continue;
while (nnext[nnext[j]]) nnext[j]=nnext[nnext[j]];
ans+=(i-nnext[j]);
}
printf("%lld\n",ans);
}

3、传送门:http://begin.lydsy.com/JudgeOnline/problem.php?id=2726

  题目大意:给出一个字母组成的矩阵,找出一个最小的子矩阵,使得这个子矩阵的无限复制扩张之后的矩阵包含原来矩阵如:         

        ABABA

        ABABA 
        他的最小重复子矩阵是AB

  题解:还是kmp,只不过要有一点小技巧,就是把一行当作一个元素,那么就有n个元素,然后做kmp找重复子串,那么最小重复子串就为n-next[n],列也做此操作,答案就是

      (n-r[n])*(m-c[m]);

  

 #include <cstdio>
#include <cstring>
char s[][], rs[][];
int R[], C[];
int r, c; void get_nextR()
{
R[] = -;
int j = -, i = ;
while(i < r)
{
if(j == - || strcmp(s[i], s[j]) == )
{
i++;
j++;
R[i] = j;
}
else
j = R[j];
}
} void get_nextC()
{
C[] = -;
int j = -, i = ;
while(i < c)
{
if(j == - || strcmp(rs[i], rs[j]) == )
{
i++;
j++;
C[i] = j;
}
else
j = C[j];
}
} int main()
{
while(scanf("%d %d", &r, &c) != EOF)
{
for(int i = ; i < r; i++)
scanf("%s", s[i]);
get_nextR();
for(int i = ; i < r; i++)
for(int j = ; j < c; j++)
rs[j][i] = s[i][j];
get_nextC();
printf("%d\n", (r - R[r]) * (c - C[c]));
}
}

4、传送门:http://begin.lydsy.com/JudgeOnline/problem.php?id=2724

  题目大意:给定一个字符串,要求找到同时是它前缀也是后缀的字符串的个数,并且输出他们的长度。

  题解:理解一下next数组的用法,从next[n]一直往前求next,那么那些点的坐标就是answer。

 #include<iostream>
#include<cstring>
#include<cstdio>
#define maxn 1000100
int n,ans,fix;
int nnext[maxn];
char s[maxn];
using namespace std;
void show(int n)
{
if (n<=) return;
show(nnext[n]);
printf("%d ",n);
}
int main()
{
scanf("%d",&n);
scanf("%s",s+);
fix=;
for (int i=; i<=n; i++)
{
while (fix && s[fix+]!=s[i]) fix=nnext[fix];
if (s[fix+]==s[i]) fix++;
nnext[i]=fix;
}
show(n);
return ;
}

5、传送门:http://begin.lydsy.com/JudgeOnline/problem.php?id=2723

 题目大意:

    现在给一个字符串A,和另一个字符串B。要你每次从B串中从左到右第第一个A串。 
    并且从B串中删除它,直到A串不为B串的子串。问需要几次删除操作。

  题解:next数组的应用,只不过用一个堆记录那些没匹配成功的字符,在用它进行匹配。

 #include<cstring>
#include<cstdio>
#include<cstring>
char t[],s[];
int m,n,top,i,fix,ans;
int z[],next[],f[];
using namespace std;
int main()
{
scanf("%s%s",t+,s+);
m=strlen(s+); n=strlen(t+);
for (fix=,i=; i<=n; i++)
{
while (fix && t[fix+]!=t[i]) fix=next[fix];
if (t[fix+]==t[i]) fix++;
next[i]=fix;
}
for (int i=; i<=m; i++)
{
fix=f[z[top]];
while (fix && t[fix+]!=s[i]) fix=next[fix];
if (t[fix+]==s[i]) fix++; if (fix==n) top-=(n-),ans++;
else
f[i]=fix, z[++top]=i;
}
printf("%d\n",ans);
}

6、传送门:http://begin.lydsy.com/JudgeOnline/problem.php?id=2719

  题目大意:给出一个串S,它包含 N 个字符。设 Pi = S [ 1 .. I ] ,对于一些 Pi , 如果Pi能表示成K个字符串相连而成的(K > 1 ,且K尽量大),则打印I和K。

  题解:如果i mod(i-next[i]) =0 && (i/(i-next[i])>1 输出答案(i);

 #include<iostream>
#include<cstring>
#include<cstdio>
#define inf 0x7fffffff
int n,ans;
int nnext[];
char s[];
using namespace std;
int main()
{
int z=;
while (true)
{
scanf("%d",&n);
if (n==) break;
z++;
printf("Test case #%d\n",z);
scanf("%s",s+);
ans=;
int fix=;
for (int i=; i<=n; i++)
{
while (fix && s[fix+]!=s[i]) fix=nnext[fix];
if (s[fix+]==s[i]) fix++;
nnext[i]=fix;
}
for (int i=; i<=n; i++)
{
int k=i-nnext[i];
if (i % k== && i/k>) printf("%d %d\n",i,i/k);
}
printf("\n");
}
}

7、传送门:http://begin.lydsy.com/JudgeOnline/problem.php?id=2720

  题目大意:给你一个字符串,它是由某个字符串不断自我连接形成的。 但是这个字符串是不确定的,现在只想知道它的最短长度是多少.

  题解:同上;

 #include<iostream>
#include<cstring>
#include<cstdio>
#define inf 0x7fffffff
int n,ans;
int nnext[];
char s[];
using namespace std;
int main()
{
scanf("%d",&n);
scanf("%s",s+);
ans=;
int fix=;
for (int i=; i<=n; i++)
{
while (fix && s[fix+]!=s[i]) fix=nnext[fix];
if (s[fix+]==s[i]) fix++;
nnext[i]=fix;
}
printf("%d\n",n-nnext[n]);
}

2016——3——16 kmp 7题的更多相关文章

  1. mysql查询练习题-2016.12.16

    >>>>>>>>>> 练习时间:2016.12.16 编辑时间:2016-12-20-->22:12:08 题: 涉及:多表查询.ex ...

  2. 2016.8.16上午纪中初中部NOIP普及组比赛

    2016.8.16上午纪中初中部NOIP普及组比赛 链接:https://jzoj.net/junior/#contest/home/1334 这次也翻车了,感觉比之前难多了. 辛辛苦苦改完了,太难改 ...

  3. zstu.4194: 字符串匹配(kmp入门题&& 心得)

    4194: 字符串匹配 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 206  Solved: 78 Description 给你两个字符串A,B,请 ...

  4. 【转载】webstorm11(注册,激活,破解,码,一起支持正版,最新可用)(2016.11.16更新)

    很多人都发现 http://idea.lanyus.com/ 不能激活了 很多帖子说的 http://15.idea.lanyus.com/ 之类都用不了了 最近封的厉害仅作测试 选择 License ...

  5. HDU 1711 Number Sequence(KMP裸题,板子题,有坑点)

    Number Sequence Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  6. 51Nod 1277 字符串中的最大值(KMP,裸题)

    1277 字符串中的最大值 题目来源: Codility 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 一个字符串的前缀是指包含该字符第一个字母的连续子串,例如: ...

  7. poj-2406(kmp水题)

    题意:定义一个a*b=字符串a连接字符串b:给你一个字符串s,问你这个字符串最多能用多少个字符串t连接得到:例如:aaaa=4个a构成: 解题思路:kmp水题,next数组除了查找字串以外最广泛的一种 ...

  8. HDU 1711 - Number Sequence - [KMP模板题]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1711 Time Limit: 10000/5000 MS (Java/Others) Memory L ...

  9. POJ 3167 Cow Pattern ★(KMP好题)

    题意 给你一个数字序列S,再给一个数字序列pattern,S和pattern中的数字都是1到s(s<=25).每个序列里的数字都有个排名,也就是第几小,现在我们要用pattern来匹配S.在本题 ...

随机推荐

  1. java项目开发第五天——奋力完成数据库

    又一次成功地避开了UI界面,看来以后在这个部分得残了,无奈,心塞,不知为何.今天人品不好,大清早在群里签到居然和机器人聊起来了,顿时感觉智商被碾压,还下载了一个QQ空间背景复制器,看了看果真是实现了, ...

  2. 转: window中使用PSFTP/WinSCP实现SFTP上传下载

    sftp 服务器:  dbmonitor 1.sftp属于交互式的,所以你得缓存下命令#!/bin/shsftp -o Port=3322 root@172.16.1.21:/opt << ...

  3. Android Paint画笔及Color .

    引自:http://blog.csdn.net/q445697127/article/details/7736926 Paint paint = new Paint(); // 设置paint为无锯齿 ...

  4. 关于Application.Lock…Application.Unlock有什么作用?

    因为Application变量里一般存储的是供所有连接到服务器的用户共享的信息(就像程序中所说的 "全局变量 "), 由于是全局变量,所以就容易出现两个或者多个用户同时对这一变量进 ...

  5. DRAM Memory Rank知识

    DRAM的一些知识点,先记录下来再进行整理 1.何为Memory rank? A memory rank is a set of DRAM chips connected to the same ch ...

  6. MFC-----在MFC中使用Picture控件加载任意图片

    对于刚刚接触OpenCV的童鞋来说,如何在MFC中加载并显示一张图片.应该是初期必定会碰到的问题之一.因此本文在分享这方面经验的同时,也相当于是写给自己的一份备忘录. 本文使用的是OpenCV2.1+ ...

  7. 2快速掌握OMD

    我们已经知道使用ArcGIS Engine开发,也就意味着我们要和接口打交道,ArcGIS Engine中提供的接口和类加起来估计上万,但是用过ArcGIS Engine的人,知道这个数字不为过.Ar ...

  8. ural1470 UFOs

    UFOs Time limit: 2.0 secondMemory limit: 64 MB Vasya is a ufologist and his duties include observing ...

  9. Mac下eclipse导入其他工程中文注释出现乱码解决方案

    因为用的是mac版的eclipse,导入其他工程注释出现乱码的情况,找了网上的很多方法,大部分都是说的workspace,在这里修改,但是我修改之后还是乱码,最后发现这样一个方法,才得以解决. 点击 ...

  10. 实战3--项目开始--准备:::资源分类, 日志系统, 写BaseDao

     项目资源分类: 1.   package: base, dao, dao.impl, domain, service, service.impl, util, view.action 2.   co ...