HDU3068 最长回文 manachar Pascalの多行字符串输入

来源:互联网 发布:nginx 经典书籍 编辑:程序博客网 时间:2024/06/05 10:00

Problem Description
给出一个只由小写英文字符a,b,c…y,z组成的字符串S,求S中最长回文串的长度.
回文就是正反读都是一样的字符串,如aba, abba等

Input
输入有多组case,不超过120组,每组输入为一行小写英文字符a,b,c…y,z组成的字符串S
两组case之间由空行隔开(该空行不用处理)
字符串长度len <= 110000

Output
每一行一个整数x,对应一组case,表示该组case的字符串中所包含的最长回文长度.

Sample Input
aaaa

abab

Sample Output
4
3

算法简介

首先manachar是一个O(N)的算法,它的作用是判断一个字符串的最长回文子串
在每两个字符以及字符串的头和尾中加一个奇怪的字符,一般我们选用#
我们设p[i]为以i这个位置为回文的中心,可以获得半径为p[i]的回文串

它的优点

1:相信大家做回文串的时候对一件事情都会感到特别烦:回文可能是偶数的也可能是奇数的,一般的做法中我们需要分开处理这两种情况,但是manachar运用了一个巧妙的方法(在每两个字符以及字符串的头和尾中加一个奇怪的字符,一般我们选用#),这样我们就可以同时处理出奇数个数和偶数个数长度的回文串了
2:我们可以发现,对于以i为中心的最长回文串,它的长度就是p[i]-1(这里面有很多种情况,分类讨论后可以发现这一规律,不再赘述),所以我们只要求出p[i]就好了

算法实现

首先我们找出在以[1..i]中一个位置为中心,可以向右到最远位置的那个位置,我们设它为id,而当前到过的最远的位置为mx
那么现在有两种情况
1:i>=mx 此时p[i]的最小值显然为1
2:i<mx 那么我们发现有s[2*id-i]=s[i] (2 *id-i,i关于id对称)而且都在以id为中心的回文串内
那么根据回文串的定义,我们似乎可以得到p[i]的最小值为p[2*id-i],因为对称性的关系
但是如果i+p[2*id-i]>mx呢?这已经超出当前找过的最远位置了,显然我们不知道后面这些位置是否能和前面匹配
所以p[i]:=min(p[2*id-i],mx-i)
然后我们在这个最小值的基础上往后面扩展
显然每次扩展必定导致mx+1
所以这个算法是O(N)的

在字符串的第一位可以加入另外一个奇怪的字符,防止越界
注意数组范围要开两倍再多一点

贴代码

var    s:array[0..230005]of char;    p:array[0..230005]of longint;    i,j,k,l,m,n,id,mx,ans:longint;    ch:char;function min(x,y:longint):longint;begin    if x<y then exit(x) else exit(y);end;begin    //assign(input,'hdu_3068.in'); reset(input);    while not eof do    begin        n:=2;        s[1]:='!';        s[2]:='#';        while not eoln do        begin            read(ch);            inc(n);            s[n]:=ch;            inc(n);            s[n]:='#';        end;        readln;        id:=0;        mx:=0;        ans:=0;        for i:=1 to n do        begin            if i<mx then p[i]:=min(p[2*id-i],mx-i) else            p[i]:=1;            while (s[i+p[i]]=s[i-p[i]]) do inc(p[i]);            if p[i]>ans then ans:=p[i];            if i+p[i]>mx then            begin                id:=i;                mx:=i+p[i];            end;        end;        readln;        writeln(ans-1);    end;   // close(input);end.
0 0
原创粉丝点击