题意:给出一个字符串,现在可以在这个字符串的右边任意添加字符串使字符串成为回文串,问回文串最短长度。
题解:因为只能在右边添加字符,添加的越少越好,所以要找一个最靠近右端点的回文串,在manacher算法中,如果出现 i + f[i] >= len说明出现了这样的串(最坏情况就是最后一个字母,回文长度是1),计算这个串的回文长度temp,结果就是2 * len - temp。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e6 + 1e6 + 100;
char str[N];
int f[N], pos;
int manacher(char *s, int len) {
int id = 0;
for (int i = len; i >= 0; i--) {
s[i + i + 2] = s[i];
s[i + i + 1] = '#';
}
s[0] = '$';
int len1 = 2 * len + 1;
for (int i = 2; i < len1; i++) {
if (f[id] + id > i) f[i] = min(f[id * 2 - i], f[id] - i + id);
else f[i] = 1;
while (s[i + f[i]] == s[i - f[i]]) ++f[i];
if (f[i] + i > id + f[id]) id = i;
if (f[i] + i >= len1)
return len1 - i;
}
}
int main() {
int t, cas = 1;
scanf("%d", &t);
while (t--) {
scanf("%s", str);
int len = strlen(str);
int res = manacher(str, len);
printf("Case %d: %d\n", cas++, len - res + len);
}
return 0;
}