KMP-Martian Strings-CF149E

2023-10-14 06:40
文章标签 kmp strings martian cf149e

本文主要是介绍KMP-Martian Strings-CF149E,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

KMP-Martian Strings-CF149E

题意:

给 定 长 度 为 n 的 母 串 s 以 及 q 个 模 式 串 p , 计 算 这 q 个 模 式 串 当 中 , 能 够 由 s 中 的 两 个 不 重 叠 的 连 续 子 串 拼 接 而 成 的 数 量 。 抽 象 地 , 即 s [ a , b ] + s [ c , d ] = p , 且 1 < = a < = b < c < = d < = n , 这 就 对 子 串 的 顺 序 和 长 度 产 生 了 限 制 。 给定长度为n的母串s以及q个模式串p,计算这q个模式串当中,能够由s中的两个不重叠的连续子串拼接而成的数量。\\抽象地,即s[a,b]+s[c,d]=p,且1<=a<=b<c<=d<=n,这就对子串的顺序和长度产生了限制。 nsqpqss[a,b]+s[c,d]=p1<=a<=b<c<=d<=n

样 例 : 输 入 : A B C B A B A 2 B A A B A B B A 对 第 一 个 模 式 串 而 言 A B 的 位 置 在 B A 的 左 侧 , 不 满 足 条 件 。 对 第 二 个 模 式 串 , a = 1 , b = 2 , c = 3 , d = 4 或 c = 5 , d = 6 均 满 足 条 件 , 因 此 有 1 个 模 式 串 满 足 条 件 。 输 出 : 1 样例:\\输入:\\ABCBABA \\2 \\BAAB \\ABBA\\对第一个模式串而言AB的位置在BA的左侧,不满足条件。\\对第二个模式串,a=1,b=2,c=3,d=4或c=5,d=6均满足条件,因此有1个模式串满足条件。\\输出:1 ABCBABA2BAABABBAABBAa=1,b=2,c=3,d=4c=5,d=611

数 据 范 围 : 母 串 长 度 n ∈ [ 2 , 100000 ] , 模 式 串 数 量 q ∈ [ 1 , 100 ] , 模 式 串 长 度 m ∈ [ 1 , 1000 ] 。 数据范围:母串长度n∈[2,100000],模式串数量q∈[1,100],模式串长度m∈[1,1000]。 n[2,100000]q[1,100]m[1,1000]

题解:

对 母 串 和 模 式 串 正 向 k m p 求 最 大 前 缀 的 长 度 , 反 向 k m p 求 最 大 前 缀 的 长 度 , 若 两 者 长 度 之 和 大 于 等 于 模 式 串 长 度 m , 说 明 可 行 。 对母串和模式串正向kmp求最大前缀的长度,反向kmp求最大前缀的长度,\\若两者长度之和大于等于模式串长度m,说明可行。 kmpkmpm

当 然 , 要 考 虑 最 大 前 缀 所 在 的 位 置 , 如 样 例 1 。 当然,要考虑最大前缀所在的位置,如样例1。 1

具体落实:

① 、 用 数 组 l e n 来 保 存 当 前 位 置 所 能 匹 配 的 最 大 长 度 。 l e n [ i ] : s 中 前 i 个 字 符 能 够 与 p 的 最 大 匹 配 的 长 度 。 ①、用数组len来保存当前位置所能匹配的最大长度。len[i]:s中前i个字符能够与p的最大匹配的长度。 lenlen[i]sip

② 、 对 模 式 串 p 求 N e x t 数 组 , 再 利 用 k m p 将 其 与 s 进 行 匹 配 , 同 时 计 算 出 l e n 数 组 。 ②、对模式串p求Next数组,再利用kmp将其与s进行匹配,同时计算出len数组。 pNextkmpslen

③ 、 将 s 与 p 翻 转 , 再 对 翻 转 后 的 p 求 N e x t 数 组 。 ③、将s与p翻转,再对翻转后的p求Next数组。 sppNext

④ 、 翻 转 后 的 p 再 与 s 进 行 匹 配 , 同 时 计 算 是 否 满 足 条 件 。 设 翻 转 后 s 匹 配 到 位 置 i , p 匹 配 到 位 置 j , j 同 时 也 是 当 前 匹 配 的 后 缀 的 长 度 , 对 翻 转 之 后 的 s 而 言 , i 之 后 的 子 串 能 够 与 p 匹 配 成 功 的 最 大 长 度 应 为 l e n [ n − i ] , 若 j + l e n [ n − j ] > = m 说 明 能 够 拼 接 成 功 。 ④、翻转后的p再与s进行匹配,同时计算是否满足条件。\\ \qquad设翻转后s匹配到位置i,p匹配到位置j,j同时也是当前匹配的后缀的长度,\\ \qquad对翻转之后的s而言,i之后的子串能够与p匹配成功的最大长度应为len[n-i],\\ \qquad若j+len[n-j]>=m说明能够拼接成功。 pssipjj,siplen[ni]j+len[nj]>=m

如 下 图 : 如下图:
在这里插入图片描述

注 意 : ① 、 由 数 据 范 围 知 道 , 两 个 子 串 的 长 度 都 应 当 大 于 0 , 即 j 与 l e n [ n − j ] 必 须 大 于 0 。 因 此 , 若 模 式 串 p 的 长 度 m = 1 , 则 无 法 满 足 条 件 。 ② 、 每 处 理 完 一 个 模 式 串 p , 要 将 s 翻 转 回 来 。 注意:\\①、由数据范围知道,两个子串的长度都应当大于0,即j与len[n-j]必须大于0。\\ \qquad因此,若模式串p的长度m=1,则无法满足条件。\\②、每处理完一个模式串p,要将s翻转回来。 0jlen[nj]0pm=1ps


代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=2e5+10;
int q,n,m,cnt;
char s[N],p[N];
int Next[1010],len[N];void get_next()
{for(int i=2,j=0;i<=m;i++){while(j&&p[i]!=p[j+1]) j=Next[j];if(p[i]==p[j+1]) j++;Next[i]=j;}
}void kmp()
{for(int i=1,j=0;i<=n;i++){while(j&&s[i]!=p[j+1]) j=Next[j];if(s[i]==p[j+1]) j++;len[i]=max(len[i-1],j);if(j==m) j=Next[j];}
}int main()
{scanf("%s",s+1);n=strlen(s+1);scanf("%d",&q);while(q--){memset(Next,0,sizeof(Next));memset(len,0,sizeof(len));scanf("%s",p+1);m=strlen(p+1);get_next();if(m==1) continue;kmp();reverse(s+1,s+1+n);reverse(p+1,p+1+m);get_next();for(int i=1,j=0;i<=n;i++){while(j&&s[i]!=p[j+1]) j=Next[j];if(s[i]==p[j+1]) j++;if(j&&len[n-i]&&j+len[n-i]>=m){cnt++;break;}if(j==m) j=Next[j];}reverse(s+1,s+1+n);}printf("%d\n",cnt);return 0;
}

这篇关于KMP-Martian Strings-CF149E的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/208818

相关文章

codeforces535D:Tavas and Malekas(KMP)

(i-1 , i)有重合的时候 ,从第i位开始的子串必须是模式串的前缀。 而同时,从第i位开始的子串本来就已经是模式串的后缀了。 typedef long long LL ;const int maxn = 1000008 ;int next[maxn] ;void getnext(char s[]){int len = strlen(s) ;next[0] = -1 ;i

fzu 2275 Game KMP

Problem 2275 Game Time Limit: 1000 mSec    Memory Limit : 262144 KB  Problem Description Alice and Bob is playing a game. Each of them has a number. Alice’s number is A, and Bob’s number i

KMP 详解

KMP数组存的是什么 对于一个字符串 b,下标从1开始。 则kmp[i]表示 以i结尾的连续子串 = s的前缀的最大值(等价于前缀最大结尾处) 如何求KMP 假设 i 以前的KMP都被求出来了。 j 表示上一个字符可以成功匹配的长度(等价于下标) 如果b[j+1] != b[i]下一个位置匹配不上(即不能成为前缀) 则,让j = kmp[j] 即成为以j结尾的 连续子串 的 最长前缀

[LeetCode] 583. Delete Operation for Two Strings

题:https://leetcode.com/problems/delete-operation-for-two-strings/description/ 题目 Given two words word1 and word2, find the minimum number of steps required to make word1 and word2 the same, where in

KMP算法详解 --- 彻头彻尾理解KMP算法

前言     之前对kmp算法虽然了解它的原理,即求出P0···Pi的最大相同前后缀长度k。   但是问题在于如何求出这个最大前后缀长度呢?   我觉得网上很多帖子都说的不是很清楚,总感觉没有把那层纸戳破,   后来翻看算法导论32章 字符串匹配,虽然讲到了对前后缀计算的正确性,但是大量的推理证明不大好理解,没有与程序结合起来讲。   今天我在这里讲一讲我的一些理解,希望大家多多指教

扩展KMP --- HDU 3613 Best Reward

Best Reward Problem's Link:   http://acm.hdu.edu.cn/showproblem.php?pid=3613   Mean:  给你一个字符串,每个字符都有一个权值(可能为负),你需要将这个字符串分成两个子串,使得这两个子串的价值之和最大。一个子串价值的计算方法:如果这个子串是回文串,那么价值就是这个子串所有字符权值之和;否则价值为0。

Swift 3.0 学习 -- 大写和小写字符串(Uppercase and Lowercase Strings)

在swift2.0的时候,您可以通过字符串的uppercaseString和lowercaseString属性来访问大写/小写版本的字符串。如下:

If an application has more than one locale, then all the strings declared in one language should als

字符串资源多国语言版本的出错问题 假如你仅仅针对国内语言 加上这句即可 //保留中文支持resConfigs "zh"

数据结构串的实现以及KMP改进算法

</pre><pre name="code" class="cpp">#include <stdio.h>#include <stdlib.h>#define OK 1#define ERROR 0#define TRUE 1#define FALSE 0#define MAXSIZE 40 /* 存储空间初始分配量 */typedef int Status; /* Status是

JavaScript - First step - Strings

var string = 'The revolution will not be televised.';var string = "The revolution will not be televised."; 转义字符 var bigmouth = 'I\'ve got no right to take my place...';bigmouth; 字符串连接 var one =