kmp求最短的回文字符串light OJ1258

该博客探讨了如何利用KMP算法解决一个编程问题:给定一个字符串,找到添加最少字符使其变成回文串的最小长度。通过反转字符串并用KMP进行模式匹配,可以确定前后部分的最大匹配数,从而得出答案。注意,关键在于寻找前后的最大匹配,而非最长公共子串。
摘要由CSDN通过智能技术生成

题目链接https://vjudge.net/contest/315202#problem/K

给一个字符串,在它右边添加字符,把它变为一个回文串,问这个回文串的最小长度

这个题有点难想到用kmp。

把它反转之后的字符串作为模式串,去和原字符匹配。找出能够匹配的字符个数x,不能匹配的个数len-x,答案就是len+len-x

但是匹配的时候,不是求最大的相同子串长度。因为最大的子串可能在字符串的中间产生。而这题很明显是求前后的最大匹配个数

没有意识到这一点,我一直wa。。。

#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#include<queue>
#include<map>
using namespace std;
char s[1000005],re[1000005];
int Next[1000005],n;
void getnext()
{
    int i=0,j=-1;
    Next[0]=-1;
    while(i<n)
    {
        if(j==-1||re[i]==re[j])
        {
            i++;
            j++;
            //if(re[i]==re[j])
            //Next[i]=Next[j];
            Next[i]=j;
        }
        else j=Next[j];
    }
}
int main()
{
    int C,i,j,cas=0,ans;
    scanf("%d",&C);
    cin.get();
    while (C--)
    {
        scanf("%s",s);
        n=strlen(s);//n代表字符串长度
        for(i=0;i<n;i++)
        {
            re[n-i-1]=s[i];
        }//反转字符串
        re[n]=0;s[n]=0;
        //cout<<s<<endl<<re<<endl;
        getnext();
        i=0;j=0;
        while(i<n)
        {
            if(j==-1||s[i]==re[j])
            {
                i++;
                j++;
            }
            else j=Next[j];
        }//求原字符串的后缀和反转后的字符串的前缀最大相同序列长度
        ans=2*n-j;
        printf("Case %d: %d\n",++cas,ans);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值