[ CODEVS ][ MANACHER回文 ] 1568 奶牛回文

裸Manacher算法题,开一个rank[i]记录映射关系。

 

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cctype>
#include<algorithm>
#include<iterator>
const int maxn = 20000 + 10;
using namespace std;
char s[maxn], in[maxn];
int rank[maxn], p[maxn], id, mx;
bool check(char t) {
	if(t >= 'a'&& t <='z'||t >= 'A'&&t <= 'Z') return true;
	else return false;
}
int main() {
	string src, dst;
	for(int i = 0; ; i++) {
		scanf("%c", &in[i]);
		if(in[i] == EOF) break;
	}
	src = in;
	transform(src.begin(), src.end(), back_inserter(dst), ::toupper);
    transform(src.begin(), src.end(), dst.begin(), ::tolower);
    int len = 0;
    for(int i = 0; i < dst.length(); i++) {
		if(check(dst[i])) { s[len] = dst[i]; rank[len] = i; len++;}
	}
	len *= 2;
	for(int i = len; i >= 0; i--) { 
		if(i & 1) s[i] = s[i / 2];
		else s[i] = '#';
	}
	int pmax = 0;
	for(int i = 0; i <= len; i++) {
		if(i >= mx) p[i] = 1;
		else p[i] = min(mx - i + 1, p[2 * id - i]);
		while(i - p[i] >= 0 && i + p[i] <= len && s[i + p[i]] == s[i - p[i]]) p[i]++;
		if(i + p[i] - 1 >= mx) {
			mx = i + p[i] - 1;
			id = i;
		}
		pmax = max(pmax, p[i]);
	}
	int k;
	for(k = 0; k < len; k++) {
		if(p[k] == pmax) break; 
	}
	int l = k - (p[k] - 1); int r = k + (p[k] - 1); r--;
	l /= 2, r /= 2;
	l = rank[l];
	r = rank[r];
	cout << pmax - 1 << endl;
	for(int i = l; i <= r; i++) cout << src[i];
	return 0;
}

  

posted @ 2017-03-18 16:43  Kvar_ispw17  阅读(171)  评论(0编辑  收藏  举报