import java.util.Scanner;
public class Main {
public static void main(String[] arg) {
Scanner scanner = new Scanner(System.in);
// todo
}
}
NC200546. 回文串
描述
输入描述
一行一个只由小写字母组成的字符串 S 。保证。
输出描述
一行一个整数,表示答案。
示例1
输入:
abccbaa
输出:
7
说明:
第一个回文串为 "abccba",第二个回文串为 "a" 长度和为 7C++14(g++5.4) 解法, 执行用时: 21ms, 内存消耗: 5580K, 提交时间: 2020-06-17 11:05:04
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;const int N=4e6+5;char s[N],t[N];int n,mr,mid,ans,r[N],f[N],g[N];void manacher(char *t,int *f){r[0]=1;for(int i=1; i<=n; i++){r[i]=0;if(i<mr)r[i]=min(r[mid*2-i],mr-i);while(t[i+r[i]]==t[i-r[i]]&&i-r[i]>=0)f[i+r[i]]=max(f[i+r[i]],r[i]+1),++r[i];if(i+r[i]>mr)mid=i,mr=i+r[i];}}int main(){scanf("%s",s),n=strlen(s);for(int i=0; i<n; i++)t[i*2]='#',t[i*2+1]=s[i];t[n*2]='#',n<<=1;manacher(t,f),reverse(t,t+n+1),manacher(t,g);for(int i=1; i<=n; i++)f[i]=max(f[i],f[i-1]);for(int i=1; i<=n; i++)g[i]=max(g[i],g[i-1]);for(int i=1; i<n; i++){if(i&1)ans=max(ans,f[i+1]+g[n-i-1]-2);elseans=max(ans,f[i]+g[n-i]-2);}printf("%d\n",ans);return 0;}
C++11(clang++ 3.9) 解法, 执行用时: 26ms, 内存消耗: 5752K, 提交时间: 2020-01-10 22:07:55
#include<bits/stdc++.h>using namespace std;const int N=4e6+5;char s[N],t[N];int n,mr,mid,ans,r[N],f[N],g[N];void manacher(char *t,int *f){r[0]=1;for(int i=1;i<=n;i++){r[i]=0;if(i<mr) r[i]=min(r[mid*2-i],mr-i);while(t[i+r[i]]==t[i-r[i]]&&i-r[i]>=0)f[i+r[i]]=max(f[i+r[i]],r[i]+1),++r[i];if(i+r[i]>mr) mid=i,mr=i+r[i];}}int main(){scanf("%s",s),n=strlen(s);for(int i=0;i<n;i++)t[i*2]='#',t[i*2+1]=s[i];t[n*2]='#',n<<=1;manacher(t,f),reverse(t,t+n+1),manacher(t,g);for(int i=1;i<=n;i++) f[i]=max(f[i],f[i-1]);for(int i=1;i<=n;i++) g[i]=max(g[i],g[i-1]);for(int i=1;i<n;i++){if(i&1) ans=max(ans,f[i+1]+g[n-i-1]-2);else ans=max(ans,f[i]+g[n-i]-2);}printf("%d\n",ans);return 0;}