hdu poj KMP简单题目总结
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简单题目总结的更多相关文章
- Least Common Multiple (HDU - 1019) 【简单数论】【LCM】【欧几里得辗转相除法】
Least Common Multiple (HDU - 1019) [简单数论][LCM][欧几里得辗转相除法] 标签: 入门讲座题解 数论 题目描述 The least common multip ...
- 七夕节 (HDU - 1215) 【简单数论】【找因数】
七夕节 (HDU - 1215) [简单数论][找因数] 标签: 入门讲座题解 数论 题目描述 七夕节那天,月老来到数字王国,他在城门上贴了一张告示,并且和数字王国的人们说:"你们想知道你们 ...
- Cyclic Nacklace HDU 3746 KMP 循环节
Cyclic Nacklace HDU 3746 KMP 循环节 题意 给你一个字符串,然后在字符串的末尾添加最少的字符,使这个字符串经过首尾链接后是一个由循环节构成的环. 解题思路 next[len ...
- SDUT-2772_数据结构实验之串一:KMP简单应用
数据结构实验之串一:KMP简单应用 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 给定两个字符串string1和str ...
- hdu 1686 KMP模板
// hdu 1686 KMP模板 // 没啥好说的,KMP裸题,这里是MP模板 #include <cstdio> #include <iostream> #include ...
- HDU 2085 核反应堆 --- 简单递推
HDU 2085 核反应堆 /* HDU 2085 核反应堆 --- 简单递推 */ #include <cstdio> ; long long a[N], b[N]; //a表示高能质点 ...
- SDUT 2772 数据结构实验之串一:KMP简单应用
数据结构实验之串一:KMP简单应用 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Problem Description 给定两个 ...
- hdu 4300(kmp)
题意:说实话这个题的题意还真的挺难懂的,我开始看了好久都没看懂,后来百度了下题意才弄懂了,这题的意思就是首先有一个字母的转换表,就是输入的第一行的字符串,就是'a'转成第一个字母,'b'转成转换表的第 ...
- SDUT OJ 数据结构实验之串一:KMP简单应用 && 浅谈对看毛片算法的理解
数据结构实验之串一:KMP简单应用 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Discuss Problem Descr ...
随机推荐
- 11.7NOIP模拟题
/* 有循环节 */ #include<cstdio> #include<cstring> #include<iostream> #include<algor ...
- 慕课网6-4 编程练习:jQuery选择器中的过滤器
6-4 编程练习 结合所学的jQuery过滤器知识,实现如下图所示的隔行换色效果 任务 使用jQuery的.css()方法设置样式,语法css('属性 '属性值') 使用:odd和:even过滤器实现 ...
- Swift5.1 语言指南(二十九)高级运算符
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- [ZJOI2005]沼泽鳄鱼
题目描述 潘塔纳尔沼泽地号称世界上最大的一块湿地,它地位于巴西中部马托格罗索州的南部地区.每当雨季来临,这里碧波荡漾.生机盎然,引来不少游客. 为了让游玩更有情趣,人们在池塘的中央建设了几座石墩和石桥 ...
- 思维题 URAL 1409 Two Gangsters
题目传送门 /* 思维题:注意题目一句话:At some moment it happened so that they shot one and the same can. 如果两个人都有射中的话, ...
- 392 Is Subsequence 判断子序列
给定字符串 s 和 t ,判断 s 是否为 t 的子序列.你可以认为 s 和 t 中仅包含英文小写字母.字符串 t 可能会很长(长度 ~= 500,000),而 s 是个短字符串(长度 <=10 ...
- Java 8 (8) 默认方法
传统上,Java程序的接口是将相关方法按照预定组合到一起的方式.实现接口的类必须为接口中定义的方法提供一个实现,或者从父类中集成它的实现.但是,一旦类库的设计者需要更新接口,向接口中加入新的方法时候, ...
- Java编程思想读书笔记_第三章
本章提到的关于==的部分,一个完整的实验如下: class Test { public static void main(String[] args) { Integer i = new Intege ...
- poj2289 Jamie's Contact Groups
思路: 二分+最大流.实现: #include <stdio.h> #include <stdlib.h> #include <limits.h> #include ...
- 前端--2、CSS基础
CSS的部分: CSS四种类引入方式(了解) style的定义原则: 基本选择器 示例: 层级选择器 组合选择器 后代选择器 ★ 子代选择器 毗邻选择器 普通兄弟选择器 “与”选择器 ★ “或”选择器 ...