hdu 3068 最长回文

来源:互联网 发布:室内温度测试软件 编辑:程序博客网 时间:2024/06/05 23:08

核心思路: rad[i]=min(rad[2*id-i],maxid-i)

其实很好理解,也就是假设你在id这个点匹配到maxid都是回文的。然后你现在搜索的这个点i不超过maxid。

那么i关于id的对称点2*id-i 一定在id左边。然后其实就是对称点向左边延伸,i向右边maxid延伸。能延伸就说明是对称的,所以取最小值。

其实就是类似于dp的一个小优化!


#include"cstdio"#include"iostream"#include"cstring"#include"algorithm"#define N 110005using namespace std;char a[N],b[N*2];int rad[N*2];  // rad[i]代表以i为中心的最大回文半径int main(){    while(scanf("%s",&a[1])!=-1){       //以下标1读入方便使用        int maxl,maxid,id;        int i,len;        for(i=1;a[i];i++){         // 插入'#' 使得所有回文串为奇数            b[i*2]=a[i];            b[i*2+1]='#';        }        len=2*i;b[0]='?'; b[1]='#'; b[len]='\0';   // 防越界  头尾区别        maxid=id=0;        maxl=0;        for(i=1;i<len;i++){            if(maxid>i)  rad[i]=min(rad[2*id-i],maxid-i);  // 利用对称性优化复杂度            else  rad[i]=1;            while(b[i-rad[i]]==b[i+rad[i]]){       //对于当前点 搜索半径                rad[i]++;            }            if(rad[i]+i>maxid){                maxid=rad[i]+i;                id=i;            }            if(rad[i]>maxl) maxl=rad[i];        }        printf("%d\n",maxl-1);    }}


0 0
原创粉丝点击