最长回文子串
时间限制:
1000 ms | 内存限制:
65535 KB
难度:
4
-
描述
-
输入一个字符串,求出其中最长的回文子串。子串的含义是:在原串连续出现的字符串片段。回文的含义是:正着看和倒着看是相同的,如abba和abbebba。在判断是要求忽略所有的标点和空格,且忽略大小写,但输出时按原样输出(首尾不要输出多余的字符串)。输入字符串长度大于等于1小于等于5000,且单独占一行(如果有多组答案,输出第一组)。
-
输入
-
输入一个测试数据n(1<=n<=10);
随后有n行,每行有一个字符串。
输出
- 输出所要求的回文子串。 样例输入
-
1 Confuciuss say:Madam,I'm Adam.
样例输出
-
Madam,I'm Adam
上传者
思路:把所有字母丢进一个数组里,并且全部转为大写或者小写,并标记每一个字母在原数组里的位置(方便查找) 再然后就是从中间向两边遍历,若不相同,break,并比较当前最大值,若大于,就更新坐标,另外,由于是从中间 开始遍历,那么奇偶性显得尤为重要(下面一共有两个代码,第一个是AC的,也就是从中间找,另外一个是超时代码,是从一边开始找的)
#include<stdio.h> #include<iostream> #include<string.h> #include<algorithm> #include<ctype.h> #define maxn 5000+10 using namespace std; char buf[maxn],s[maxn]; int p[maxn]; int main() { int T; scanf("%d%*c",&T); while(T--) { int n,m=0,max=0,x,y; int i,j; gets(buf); n=strlen(buf); for(int i=0; i<n; i++) { if(isalpha(buf[i])) { p[m]=i; s[m++]=toupper(buf[i]); } } for(i=0; i<m; i++) { for(j=0; i-j>=0&&i+j<m; j++) { if(s[i-j]!=s[i+j]) break; if(j*2+1>max) { max=j*2+1; x=p[i-j]; y=p[i+j]; } } for(j=0; i-j>=0&&i+j+1<m; j++) { if(s[i-j]!=s[i+j+1]) break; if(j*2+2>max) { max=j*2+2; x=p[i-j]; y=p[i+j+1]; } } } for(i=x; i<=y; i++) printf("%c",buf[i]); printf("\n"); } return 0; }
(2)
#include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> #include<ctype.h> #define maxn 5000+10 using namespace std; char s[maxn],t[maxn],p[maxn]; int main() { int T; scanf("%d%*c",&T); while(T--) { gets(s); int n=strlen(s); int i,j,m=0,x=0,y=0,maxx=0,k=0; for(i=0; i<n; i++) { if(isalpha(s[i])) { p[m]=i; t[m++]=toupper(s[i]); } } for(i=0; i<m; i++) { for(j=i; j<m; j++) { int ok=1; for(int k=i; k<=j; k++) { if(t[k]!=t[i+j-k]) ok=0; } if(ok&&j-i+1>maxx) { maxx=j-i+1; x=p[i]; y=p[j]; } } } for(i=x; i<=y; i++) { printf("%c",s[i]); } printf("\n"); } return 0; }
-
输入一个测试数据n(1<=n<=10);