在字符串尾部添加字符,使之变成回文串
#include <iostream> #include <cstring> #include <string> #include <algorithm> using namespace std; //最长回文,Manacher算法 char s[211000], c[111000];//注意S数组的大小至少要开C数组的两倍 int p[211000];//P可以理解为回文字符串的半径 void init()//初始化S数组 { int i, j; s[0] = '@'; for (i = 0; c[i] != 0; i++) { s[2 * i + 1] = '#'; s[2 * i + 2] = c[i]; } s[2 * i + 1] = '#'; s[2 * i + 2] = 0; } void manacher() { int id = 0, mx = 0; int maxLen = 0, start = 0; for (int i = 1; s[i] != 0; i++) { if (mx > i) p[i] = min(p[2 * id - i], mx - i); else p[i] = 1; //p[i]=mx>i?min(p[2*id-i],mx-i):1; while (s[i + p[i]] == s[i - p[i]]) p[i]++; if (i + p[i] > mx) { mx = i + p[i]; id = i; } } mx = 0; for (int i = 1; s[i] != 0; i++) { if (p[i] > mx) { mx = p[i]; start = (i - p[i]) / 2; maxLen = mx - 1;//mx-1是回文子串的长度,start是回文子串的起始位置 } } //cout << start << " " << start + maxLen-1 << endl; //找到最长回文子串的起始地址start、和回文串的长度maxlen后,剩余部分,直接反序添加 string temp1 = "", temp2 = ""; if (maxLen == strlen(c))//本身就是回文串 { cout << c << endl; } else if (start + maxLen-1 == strlen(c) - 1) { for (int i = start - 1; i >= 0; i--) temp1 = temp1 + c[i]; cout << c << temp1 << endl; } else//如果回文子串不在尾部,只能整体翻转拼接在尾部才是回文串 { for (int i = strlen(c) - 1; i >= 0; i--) temp2 = temp2 + c[i]; cout << c << temp2 << endl; } } int main()//用cin\cout 会超时 { while (~scanf("%s", c)) { init(); manacher(); } return 0; }
等风起的那一天,我已准备好一切