https://codeforces.com/contest/1326/problem/D2
<문제설명>
문자열 s가 주어질 때, s의 prefix a, suffix b를 이어붙여 만들 수 있는 최대길이 팰린드롬을 출력하라.
(단, a+b<=s)
<풀이>
문자열 s의 prefix 중 최대 길이의 팰린드롬은 어떻게 구할까?
s를 뒤집은 문자열을 t라고 하고
string a = s + "#" + t;
a의 pref[a.size()-1]이 그 팰린드롬의 최대길이이다.
prefix function pref
pref[i] : i로 끝나는 문자열에서 suffix==prefix 최대길이
pref.resize(t.size());
for (int i = 1, j = 0; i < t.size(); i++) {
while (j > 0 && t[i] != t[j]) j = pref[j - 1];
if (t[i] == t[j]) pref[i] = ++j;
}
<코드>
int tt;
string inp;
string prefixPalin(string a) {
string b = a;
reverse(b.begin(), b.end());
string s = a + "#" + b; //더미문자 추가해서 s길이 홀수로 강제
vector<int> pref(s.size());
int j = 0;
for (int i = 1; i < s.size(); i++) {
while (j > 0 && s[i] != s[j]) j = pref[j - 1];
if (s[i] == s[j]) pref[i] = ++j;
}
return a.substr(0, j);
}
int main() {
FAST; cin >> tt;
while (tt--) {
cin >> inp;
int lo = 0;
while (lo < (int)inp.size()-lo-1 && inp[lo] == inp[inp.size() - 1 - lo])
lo++;
if (lo > 0)
cout << inp.substr(0, lo);
string s = inp.substr(lo, inp.size() - 2 * lo);
string a = prefixPalin(s);
reverse(s.begin(), s.end());
string b = prefixPalin(s);
if (a.size() < b.size()) swap(a, b);
cout << a;
if (lo > 0)
cout << inp.substr(inp.size() - lo, lo);
cout << '\n';
}
}
'알고리즘 > 코드포스' 카테고리의 다른 글
cf 551 div2 D - Serval and Rooted Tree (tree, dp, 발상) (0) | 2020.03.25 |
---|---|
Educational 84 div2 D - Infinite Path (약수, 수론, 후속노드그래프) (0) | 2020.03.24 |
cf 596 div2 D - Power products (소인수분해, 수학) (0) | 2020.03.15 |
cf 562 div2 C - Increasing by modulo (이분탐색, 그리디) (0) | 2020.03.15 |
cf 626 div2 D - present (수론, 이분탐색) (0) | 2020.03.15 |