题意:
取一字符串前缀和后缀(均可为空)构成最长回文串。
思路:
先同时取对称的前后缀,之后再取较长的前缀或后缀。
#include <bits/stdc++.h> using namespace std; bool ok(string &s,int l,int r){ while(s[l]==s[r]) ++l,--r; return l>=r; } void solve(){ string s;cin>>s; int l=0,r=s.size()-1; vector<char> lf,rt; while(l<=r&&s[l]==s[r]){ lf.push_back(s[l]); rt.push_back(s[r]); ++l,--r; } if(l>=r){ cout<<s<<"\n"; return; } vector<int> pos[26]; for(int i=l;i<=r;i++) pos[s[i]-'a'].push_back(i); int c1=s[l]-'a',c2=s[r]-'a'; int c1_l=l,c1_r=0; int c2_r=r,c2_l=INT_MAX; for(int i:pos[c1]){ if(ok(s,l,i)){ c1_r=max(c1_r,i); } } for(int i:pos[c2]){ if(ok(s,i,r)){ c2_l=min(c2_l,i); } } if((c1_r-c1_l)>(c2_r-c2_l)){ for(int i=c1_l;i<=c1_r;i++) lf.push_back(s[i]); }else{ for(int i=c2_r;i>=c2_l;i--) rt.push_back(s[i]); } reverse(rt.begin(),rt.end()); for(char c:lf) cout<<c; for(char c:rt) cout<<c; cout<<"\n"; } int main() { int t;cin>>t; while(t--) solve(); return 0; }