Boring Non-Palindrome 【马拉车算法】
Boring Non-Palindrome
题目链接:https://codeforces.com/gym/102307/problem/B
思路
因为只能从末尾加字符串,让其变成回文串,那么就可以找到以原字符串末尾结束的最长回文子串T(马拉车做),然后把前面不属于T的部分命名成T2。然后输出原字符串,再反序输出T2。
代码
#include<bits/stdc++.h>
#define ios ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long ll;
const int maxn = 1e4+10;
using namespace std;
string s;
int ans[maxn],str[maxn],lef[maxn];
int build(const string &s){
int n = s.length(), m = (n + 1)*2, ret = 0;
str[0] = '\n'; str[m] = '\t'; str[1] = '\r'; ans[1] = 1;
for (int i = 1; i <= n; i++)
str[i*2] = s[i - 1], str[i*2+1] = '\r';
ans[1] = 1;
for (int r = 0, p = 0, i = 2; i < m; ++i){
if (r > i) ans[i] = min(r - i, ans[p * 2 - i]);
else ans[i] = 1;
while(str[i - ans[i]] == str[i + ans[i]]) ++ans[i];
if (i + ans[i] > r) r = i + ans[i], p = i;
ret = max(ret, ans[i] - 1);
}
for (int i = 2; i < m; i++) if (lef[i - ans[i] + 1] < i + 1) lef[i - ans[i] + 1] = i + 1;
for (int i = 1; i <= m; i++) if (lef[i] < lef[i - 1]) lef[i] = lef[i - 1];
return ret;
}
int left(int x){
return lef[(x + 1) << 1] - ((x+1) << 1);
}
int main(){
ios;
cin>>s;
int len = s.length();
build(s);
int lenr = 1;
for(int i = 0;i<len;i++){
int ll = left(i);
if(i + ll - 1 == len-1) {
lenr = ll;
break;
}
}
cout<<s;
for(int i = len-lenr-1;i>=0;i--) cout<<s[i];
return 0;
}Ryuichi的算法分享 文章被收录于专栏
分享我的一些算法题解,致力于把题解做好,部分题解可能会采用视频的形式来讲解。
查看12道真题和解析