题意:多组输入,给一个字符串并输出构造(只能在尾部插入)其成为最小的回文串
思路:如果是对串任意插入的话就能有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; }