问题 A: 【字符串】最长回文子串
[命题人 : 外部导入]
时间限制 : 1.000 sec 内存限制 : 128 MB
http://codeup.hustoj.com/problem.php?cid=100000629&pid=0
题目描述
输入一个字符串,求出其中最长的回文子串。子串的含义是:在原串中连续出现的字符串片段。回文的含义是:正着看和倒着看相同。如abba和yyxyy。在判断回文时,应该忽略所有标点符号和空格,且忽略大小写,但输出应保持原样(在回文串的首部和尾部不要输出多余字符)。输入字符串长度不超过5000,且占据单独的一行。应该输出最长的回文串,如果有多个,输出起始位置最靠左的。
输入
一行字符串,字符串长度不超过5000。
输出
字符串中的最长回文子串。
样例输入 Copy
Confuciuss say:Madam,I'm Adam.
样例输出 Copy
Madam,I'm Adam
#include<cstdio>
#include<algorithm>
#include<string.h>
using namespace std;
int dp[5005][5005]={0};
int main(){
char s[5005],str[5005];
gets(s);
int k=0,p[5005];
for(int i=0;i<strlen(s);i++){
if(isalpha(s[i])||isdigit(s[i])){
p[k]=i;
if(s[i]<='9'&&s[i]>='0')str[k++]=s[i];
else if(s[i]<='Z'&&s[i]>='A')str[k++]=s[i];
else if(s[i]<='z'&&s[i]>='a')str[k++]=s[i]-32;
}
}
//printf("%s\n",str);
int len=strlen(str),ans=1,start=0;
for(int i=0;i<len;i++){
dp[i][i]=1;
if(i<len-1){
if(str[i]==str[i+1]){
dp[i][i+1]=1;
ans=2;
start=i;
}
}
}
for(int L=3;L<=len;L++){
for(int i=0;i+L-1<len;i++){
int j=i+L-1;
if(str[i]==str[j]&&dp[i+1][j-1]==1){
dp[i][j]=1;
ans=L;
start=i;
}
}
}
for(int i=p[start];i<=p[start+ans-1];i++)
printf("%c",s[i]);
return 0;
}
for(int i=0;i<strlen(s);i++)
printf("i:%d \t s[%d]:%c \t str[%d]:%c \t p:%d\n",i,i,s[i],i,str[i],p[i]);
for(int i=p[start];i<=p[start+ans-1];i++)
printf("%c",s[i]);
关于p数组是干嘛的:
在打印最后的结果之前,加两行代码把字符串数组s、str,p数组都打印出来结果如下:
p数组是用来存str数组中的每一项在原s数组中的位置的。因为计算回文串的时候用的是str数组,而最后打印的应该是s数组。