标签:字符串 end 一个 回文串 while efi 16px bsp sign
题意:给一个串s,用最少的字母补全使它成为回文串
思路:先求正反两个哈希,然后枚举终点
思维上没什么难度主要是细节以及怎么写比较自然
我选择把两个哈希串都弄成递增的,那原串s[l..r]的哈希值就是反哈希[n-r, n-l]的值
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 #define LL long long 6 #define uLL unsigned long long 7 #define debug(x) cout << "[" << x << "]" << endl 8 using namespace std; 9 10 const int mx = 1e5+10; 11 const int base = 131; 12 uLL hs[mx], ht[mx], p[mx]; 13 char s[mx]; 14 15 int main(){ 16 p[0] = 1; 17 for (int i = 1; i < mx; i++) p[i] = p[i-1]*base; 18 while (scanf("%s", s+1) == 1){ 19 int n = strlen(s+1), flag = -1; 20 for (int i = 1; i <= n; i++) { 21 hs[i] = hs[i-1]*base+s[i]-‘a‘; 22 ht[i] = ht[i-1]*base+s[n-i+1]-‘a‘; 23 } 24 int i = n/2+1; 25 while (i <= n){ 26 uLL a = hs[n]-p[n-i+1]*hs[i-1]; 27 uLL b = ht[2*n-2*i+2]-p[n-i+1]*ht[n-i+1]; 28 if (2*i-n >= 0 && a == b){ 29 flag = 0; 30 break; 31 } 32 a = hs[n]-p[n-i]*hs[i]; 33 b = ht[2*n-2*i+1]-p[n-i]*ht[n-i+1]; 34 if (i+1 <= n && a == b) { 35 flag = 1; 36 break; 37 } 38 i++; 39 } 40 printf("%s", s+1); 41 if (flag == 1){ 42 for (int j = 2*i-n-1; j >= 1; j--) 43 printf("%c", s[j]); 44 } 45 else if (!flag){ 46 for (int j = 2*i-n-2; j >= 1; j--) 47 printf("%c", s[j]); 48 } 49 else { 50 for (int j = n-1; j >= 1; j--) 51 printf("%c", s[j]); 52 } 53 printf("\n"); 54 } 55 return 0; 56 }
标签:字符串 end 一个 回文串 while efi 16px bsp sign
原文地址:https://www.cnblogs.com/QAQorz/p/9733952.html