回文POJ3974

回文POJ3974

思路

题干在这:POJ3974
回文可能是奇数个字符或者偶数个字符,我们先扫一遍字符串,算出正向和反向的hash,然后枚举中心点,二分向左右的最大延伸,取最大值即可

ac代码

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define MAX 1000010
#define P 131
using namespace std;
unsigned long long origin[MAX] = { 0 }, rever[MAX] = { 0 };
unsigned long long p[MAX] = { 1 };
char s[MAX] = { 0 };
int main() {
	int ca = 0;
	while (1) {
		gets_s(s);
		if (strcmp(s, "END") == 0)
			return 0;
		ca++;
		int len = strlen(s);
		for (int i = 1; i <= len; i++) {
			origin[i] = origin[i - 1] * P + s[i - 1] - 'a' + 1;
			rever[i] = rever[i - 1] * P + s[len - i] - 'a' + 1;
			p[i] = p[i - 1] * P;
		}
		len++;
		int maxodd = 0;
		for (int i = 2; i <= len - 1 - maxodd; i++) {
			int l = 0, r = min(i - 1, len - 1 - i);
			while (l != r) {
				int mid = (l + r) / 2 + 1;
				if (origin[i + mid] - origin[i] * p[mid] == rever[len - i + mid] - rever[len - i] * p[mid])
					l = mid;
				else
					r = mid - 1;
			}
			maxodd = max(maxodd, l);
		}
		int maxeven = 0;
		for (int i = 1; i <= len - 1 - maxodd; i++) {
			int l = 0, r = min(i, len - 1 - i);
			while (l != r) {
				int mid = (l + r) / 2 + 1;
				if (origin[i + mid] - origin[i] * p[mid] == rever[len - i + mid - 1] - rever[len - i - 1] * p[mid])
					l = mid;
				else
					r = mid - 1;
			}
			maxeven = max(maxeven, l);
		}
		cout << "Case " << ca << ": " << max(2 * maxeven, 2 * maxodd + 1) << endl;
	}
}
发布了24 篇原创文章 · 获赞 0 · 访问量 350

猜你喜欢

转载自blog.csdn.net/qq_45616764/article/details/104234325