POJ3974:Palindrome(Manacher模板)

Palindrome

Time Limit: 15000MS   Memory Limit: 65536K
Total Submissions: 14021   Accepted: 5374

题目链接:http://poj.org/problem?id=3974

Description:

Andy the smart computer science student was attending an algorithms class when the professor asked the students a simple question, "Can you propose an efficient algorithm to find the length of the largest palindrome in a string?" 

A string is said to be a palindrome if it reads the same both forwards and backwards, for example "madam" is a palindrome while "acm" is not. 

The students recognized that this is a classical problem but couldn't come up with a solution better than iterating over all substrings and checking whether they are palindrome or not, obviously this algorithm is not efficient at all, after a while Andy raised his hand and said "Okay, I've a better algorithm" and before he starts to explain his idea he stopped for a moment and then said "Well, I've an even better algorithm!". 

If you think you know Andy's final solution then prove it! Given a string of at most 1000000 characters find and print the length of the largest palindrome inside this string.

Input:

Your program will be tested on at most 30 test cases, each test case is given as a string of at most 1000000 lowercase characters on a line by itself. The input is terminated by a line that starts with the string "END" (quotes for clarity). 

Output:

For each test case in the input print the test case number and the length of the largest palindrome. 

Sample Input:

abcbabcbabcba
abacacbaaaab
END

Sample Output:

Case 1: 13
Case 2: 6

 

题意:

求最长回文串的长度。

 

题解:

直接马拉车算法套下就行了。

代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
typedef long long ll;
const int N = 2000005;
char s[N],tmp[N];;
int p[N];
void Manacher(char *s){
    memset(p,0,sizeof(p));
    int l=strlen(s);
    strcpy(tmp,s);
    s[0]='$';
    for(int i=1;i<=2*l+1;i++){
        if(i&1) s[i]='#';
        else s[i]=tmp[i/2-1];
    }
    s[2*l+2]='\0';
    int mx=0,id=0;
    l=strlen(s);
    for(int i=1;i<l;i++){
        if(i>=mx) p[i]=1;
        else p[i]=min(mx-i,p[2*id-i]);
        while(s[i-p[i]]==s[i+p[i]]) p[i]++;
        if(p[i]+i>mx){
            mx=p[i]+i;
            id=i;
        }
    }
}
int main(){
    int cnt = 0;
    while(scanf("%s",s)!=EOF){
        cnt++;
        if(s[0]=='E'&&s[1]=='N') break;
        Manacher(s);
        int ans = 0;
        int l=strlen(s);
        for(int i=1;i<l;i++) ans=max(ans,p[i]-1);
        printf("Case %d: ",cnt);
        printf("%d\n",ans);
    }
    return 0;
}

 

posted @ 2019-03-05 21:18  heyuhhh  阅读(187)  评论(0编辑  收藏  举报