Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 1027 Accepted Submission(s): 389
b babd a abcd
0 2 aza No solution!
题意:求最长回文子串,并求出起始位置。
分析:预处理移位表,之后用Manacher算法搞定
转载请注明出处:寻找&星空の孩子
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3294
//Manacher算法 #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define maxn 200010*2 int P[maxn]; //(p.s. 可以看出,P[i]-1正好是原字符串中回文串的总长度) char s1[maxn]; char s2[maxn]; char ch[30]; void manacher(char* s) { int i,id=0,mx=0; P[0]=0; //P[0]位置没用 for(i=1;s[i];i++) //对串进行线性扫描 { if(mx > i) //如果mx比当前i大,分为两种情况,详细致请看文章开头推荐的blog上的图示,非常给力的图 P[i] = min(P[2*id-i],mx-i); else //如果mx比i小,没有可以利用的信息,那么就只能从头开始匹配 P[i] = 1; while(s[i+P[i]]==s[i-P[i]] )P[i]++; //匹配 if(mx < P[i] + i) //坚持是否有更新mx以及id { mx = P[i] + i; id = i; } } } void init(int t) { int i, j = 2; s2[0] = '$', s2[1] = '#'; for(i=0;s1[i];i++) { s2[j++] = s1[i]; s2[j++] = '#'; } s2[j] = '\0'; //置换表 char ex='a'; ch[t]=ex++; for(i=t+1;(i%26)!=t;i++) { ch[i%26]=ex++; } // for(i=0;i<=25;i++) // printf("%c",ch[i]); } int main() { char gh,gg; while(scanf("%c %s%c",&gh,s1,&gg)!=EOF) { // getchar(); init(gh-'a'); manacher(s2); int ans=0,x,y; for(int i=1;s2[i]!='\0';i++) { if(P[i]>ans) { ans=P[i]; x=i; } } //printf("%d\n",ans-1); if(ans-1==1) {printf("No solution!\n");continue;} // printf("ans=%d\tx=%d\n",ans,x); // if(x&1){x=(x-1)/2;x=x-(ans-1)/2;y=x+ans-2;} // else {x=(x-1)/2;x=x-(ans-1)/2;y=x+ans-2;} //对应起始终点位置 x=(x-1)/2; x=x-(ans-1)/2; y=x+ans-2; printf("%d %d\n",x,y); for(int i=x;i<=y;i++) { printf("%c",ch[s1[i]-'a']); } printf("\n"); } return 0; } /* a abbab a abbabcba b babd a abcd */