kmp算法拓展题

蓝桥杯每日一题



前言


一、题目

问题描述
在这里插入图片描述

二、解题

1.思路

第一想法肯定会想到KMP的next数组。但这回人家问的是最短的有效前后缀长度。但比KMP简单的是,s1是由s2至少两次完整复制过来的。要知道前缀必定是从第一位开始的字符串,后缀一定是最后一位往前的字符串。我们可以想象一下s1会长什么样:
s2+s2+s2的一部分(空白也是)
那s2前面还会有字符串吗?
不可能有,因为会导致s2改变。
举个例子:
abcabca的前后缀是abca,s2是abc
cabcabca前后缀是ca,s2是ca
那问题就好做了,最长前后缀是大于或等于s2的(反证法可以证明),而前后缀大于s2的条件是:前缀形状会是s2+s2残缺,后缀形状会是s2(这个s2是用着前缀的残缺s2做开头补足的完整s2)+s2残缺。整个s1-前缀或者s1-后缀剩下的会是什么?上面已经提到过s1=s2+s2+s2残缺了,减法得出s2+s2+s2残缺-s2+s2残缺=s2!此时我们可以直接得到s2。

2.代码

#include<string>
#include<iostream>
using namespace std;
int main() {
	int s1; 
    cin >> s1;
    string s2; 
    cin >> s2;
    //模式串建立
	int kmp[100000000];
	kmp[0]=0;
	int i=0;
	int j=1;
	for(j=1;j<s2.size();j++){
		while(i&&s2[i]!=s2[j])i=kmp[i-1];
		if(s2[i]==s2[j]){
			i++;
		}
		kmp[j]=i;
	}
	cout<<s1-kmp[s1-1];
    return 0;
}

总结

写代码题没思路往往是盯着要算的问题太久了,其实题目信息可以转换成其他信息帮助我们联通到答案,冷静分析所有会出现可能,其实和以前做数学题感觉一模一样,先转换信息,然后再分类讨论。

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值