题意:
题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2470
给出一个字符串,在末尾补充最少的字母,使其整个成为一个回文串。
思路:
字符串哈希的巧妙运用,很显然如果是回文串,那么正着哈希和倒着哈希得到的值是一样的。
而通过哈希的数值来进行拼接组合可以节省大量时间。只要枚举位置x,
将[1,x]这段哈希值与求出的总的哈希值拼接,比较正哈希值与倒哈希值是否相同即可
ps:131进制是个好东西。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ULL;
const int MAXN = 1e5 + 10;
const ULL seed = 131;
char s[MAXN];
ULL f[MAXN];
int main() {
//freopen("in.txt", "r", stdin);
f[0] = 1;
for (int i = 1; i < MAXN; i++)
f[i] = f[i - 1] * seed;
while (scanf("%s", s) != EOF) {
int n = strlen(s);
ULL sum1 = 0, sum2 = 0;
for (int i = 0; i < n; i++) {
sum1 = sum1 * seed + s[i] - 'A';
sum2 = sum2 + (s[i] - 'A') * f[i];
}
if (sum1 == sum2) {
puts(s);
continue;
}
ULL add1 = 0, add2 = 0;
int pos = -1;
for (int i = 0; i < n; i++) {
add1 = add1 + (s[i] - 'A') * f[i];
add2 = add2 * seed + s[i] - 'A';
ULL tmp1 = sum1 * f[i + 1] + add1;
ULL tmp2 = sum2 + add2 * f[n];
if (tmp1 == tmp2) {
pos = i;
break;
}
}
printf("%s", s);
for (int i = pos; i >= 0; i--)
printf("%c", s[i]);
puts("");
}
return 0;
}