UVA-11475 Extend to Palindrome(KMP)

题意:多组输入,给一个字符串并输出构造(只能在尾部插入)其成为最小的回文串

思路:如果是对串任意插入的话就能有dp 对 lcs(最长公共子序列处理)的方式处理。 我们把 一个字符串s ,逆置为s1 通过dp 找到其最长公共子序列 ,然后 用原长度 减去最长公共子序列即为补全长度 (插入时的情况)

但此题是对末尾增加所以应是一个连续子串的匹配 ,所以我们使用KMP算法来匹配最长的连续子串部分,这样不相同的部分就进行补全。

完整代码:

#include<cstdio>
#include<cstring>
#include <string>
#include <iostream>
#include <cmath>
#include<algorithm>
using namespace std;
const int maxn = 1000;
int nex[maxn];
int len1,len2;
string a,b;
void getnext(){
    int i= 0,j =-1;//i为副串的序号 
    nex[i] = j;
    while(i<len2){
        if(j==-1||b[i]==b[j]){
            nex[++i] =++j;
        }else j = nex[j];
    }
}
int kmp(){

    int ans = 0;
    int cnt = 0;
    int count = 0;
    int i= 0,j=0;
    getnext();
    for(i=0;i<len1;i++)
    {
        while(j>0&&a[i]!=b[j]){
            j=nex[j];
            cnt = 0;
        }
        if(a[i]==b[j])    {
            j++; cnt++;
            count = max(cnt,count);
        }
    }
    return count;
}

int main()
{
    int lena,lenb,i,j;
    while(cin>>a)
    {
        b.assign(a);
        reverse(b.begin(),b.end()); 
        len1 = a.size();
        len2 = b.size();
        int ans = kmp();
        if(ans==len1) cout<<a<<endl; 
        else{
            string s = b.substr(ans,len1);
            cout<<a<<s<<endl;
        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Tianwell/p/11234108.html