【Manacher】【贪心】字符串连接(金牌导航 Manacher-4)
生活随笔
收集整理的這篇文章主要介紹了
【Manacher】【贪心】字符串连接(金牌导航 Manacher-4)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
正題
金牌導航 Manacher-4
題目大意
給出一個字符串,讓你用最少的回文串連接得到該串(這里連接是可以有重合的)
解題思路
先用Manacher求出以x為左端點的回文串右端點最大的位置
然后在當前回文串中貪心求下一回文串的右端點
代碼
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define ll long long #define N 50010 using namespace std; int n, now, ans, last, s[N<<1], l[N<<1], r[N<<1]; string str; void Manacher() {int mid = 0, mx = 0;for (int i = 1; i <= n; ++i){if (i < mx) l[i] = min(l[mid * 2 - i], mx - i);else l[i] = 1;while(s[i + l[i]] == s[i - l[i]]) l[i]++;if (i + l[i] > mx){mx = i + l[i];mid = i;}r[i - l[i] + 1] = i + l[i] - 1;} } int main() {while(cin>>str){memset(r, 0, sizeof(r));n = str.size();s[0] = s[1] = '#';for (int i = 1; i <= n; ++i){s[i * 2] = str[i - 1];s[i * 2 + 1] = '#';}n = n * 2 + 2;s[n] = 0;Manacher();now = last = r[1] + 2;//初始的回文串ans = 0;for (int i = 2; i <= n; ++i){if (i == last)last = now, ans++;//下一個回文串now = max(now, r[i] + 2);//貪心求最右的點}printf("%d\n", ans);}return 0; }總結
以上是生活随笔為你收集整理的【Manacher】【贪心】字符串连接(金牌导航 Manacher-4)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Manacher】绿绿和串串(luog
- 下一篇: 户外作业加固平板电脑亮度多少合适加固平板