hdu 3068 最长回文子串 manacher
2015-08-12 10:52
459 查看
最长回文
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 11393 Accepted Submission(s): 4112
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
Source
2009 Multi-University Training
Contest 16 - Host by NIT
Recommend
lcy
#include<cstdio> #include<string> #include<cstring> #include<iostream> #include<cmath> #include<algorithm> #include<climits> #include<queue> #include<vector> #include<map> #include<sstream> #include<set> #include<stack> #include<utility> #pragma comment(linker, "/STACK:102400000,102400000") #define PI 3.1415926535897932384626 #define eps 1e-10 #define sqr(x) ((x)*(x)) #define FOR0(i,n) for(int i=0 ;i<(n) ;i++) #define FOR1(i,n) for(int i=1 ;i<=(n) ;i++) #define FORD(i,n) for(int i=(n) ;i>=0 ;i--) #define lson num<<1,le,mid #define rson num<<1|1,mid+1,ri #define MID int mid=(le+ri)>>1 #define zero(x)((x>0? x:-x)<1e-15) using namespace std; const int INF =0x3f3f3f3f; const int maxn= 110000+20 ; //const int maxm= ; //const int INF= ; typedef long long ll; const ll inf =1000000000000000;//1e15; //ifstream fin("input.txt"); //ofstream fout("output.txt"); //fin.close(); //fout.close(); //freopen("a.in","r",stdin); //freopen("a.out","w",stdout); char s[maxn]; char tem[maxn<<1]; int nex[maxn<<1]; int L; void install() { tem[0]='$'; //最左边加上'$'是为了防止出界,因为字符串中一般没有字符能和'$'匹配, //字符串末尾的'\0'也是同样效果,而且必须加'\0'; int i=0,dp=0,k=1; while(s[i]) { tem[k++]= dp?s[i++]:'#'; //小技巧 dp^=1; } tem[k++]='#'; tem[L=k]='\0'; } void getnex() { int far=0,id; for(int i=1;i<L;i++) { //2*id就是以id为对称中心且0为最左点的最右点,减去i,那么就是i关于id的对成点,简单说就是中点公式 if(far>i) nex[i]=min(far-i,nex[ 2*id-i]);//开始的点最大为far-i,用min定义了一个上限 else nex[i]=1; for( ; tem[i-nex[i]]==tem[i+nex[i]] ;nex[i]++ ) if(far<i+nex[i]) far=i+nex[i],id=i; } } int main() { while(~scanf("%s",s)) { install(); getnex(); int maxi=0; for(int i=1;i<L;i++) maxi=max(maxi,nex[i]-1); //为什么是nex[i]-i;-可以这样想, //首先考虑tem[i]是否是'#',然后从i不断延伸,总是停在一 个'#'上,有成对性。 printf("%d\n",maxi); } return 0; }
相关文章推荐
- 压图地址
- Oracle创建Database Link的两种方式
- Restler 的使用
- ORACLE中date和timestamp的相互转化
- java Scanner与BufferedReader读取键盘输入性能比较
- 集训第五周 动态规划 B题LIS
- leetcode_Sort List
- 文本 字符编码(转)
- R做基本的用户行为分析
- Android开机自启动service,并不启动activity
- 更新sdk后遇到This Android SDK requires Android Developer Toolkit version 20.0.0 or above
- 汝佳大神的紫书上写错了?uva10048
- 如何计算网络地址和广播地址
- 【问题解决】Project facet Java version 1.7 is not supported.
- java设计模式之建造者模式
- 《转》Qt 经典出错信息之”Basic XLib functionality test failed!”(Z..z..)
- iOS基础-UIKit框架-高级视图-UIDatePicker
- 如何告知用户以及蜘蛛网站正在维护?
- WM_CLOSE WM_QUIT WM_DESTROY 三者的区别
- Bit Manipulation - Repeated DNA Sequences