原题:https://www.patest.cn/contests/gplt/L2-008
这道题可真是把我累的够呛,一开始是方法错了,后来是题目定义不清晰理解错误,最后终于在第12次提交成功,废话不说,总结如下:
1.对称,就是倒置之后还是不变,例如"aba",颠倒后还是"aba",所以思路就是,把原字符串s1倒置过来,变成s2,然后求s1和s2最长公共子串
2.因为s1倒置过来变成s2,那么遍历s2的过程就相当于从s1的尾部开始遍历
3.即使字符串中只有一个字符,"1"也算是一个对称子串,长度为1
代码一超时,但方便理解:
//代码一超时
#include<stdio.h>
#include<string.h>
char s1[1001];
char s2[1001];
int i,j;
int main()
{
gets(s1);
i=0;
j=strlen(s1)-1;
while(j>=0)
{
s2[i++]=s1[j--];
}
s2[i]='\0';
//获得倒置后的字符串s2
int tmp;
int max=-1;
for(i=0;i<strlen(s1);i++)
{
int k=i; //从s1的第一个字符开始
for(j=0;j<strlen(s2);j++)//从s2的第一个字符开始找
{
tmp=0; //当前最长子串长 为tmp=0
if(s1[k]==s2[j])//找到相同的字符
{
tmp++; //最长长度+1
k++;
j++; //同步查找下一个
while(k<strlen(s1)&&j<strlen(s2)&&s1[k]==s2[j])//继续遍历看看还有没有相同的字符
{
tmp++;
k++;
j++;
}
if(tmp>max){ //如果当前最长子串长比max大,就代替max
max=tmp;
}
}
}
}
printf("%d\n",max);
return 0;
}
代码二:遍历倒置字符串s2,相当于从s1的末尾开始向前遍历,不用专门倒置s1
#include<stdio.h>
#include<string.h>
char s1[1002];
int i,j;
int main()
{
gets(s1);
int tmp;
int max=1; //最长子串的长度
for(i=0;i<strlen(s1);i++)
{
int k=i; //从字符串的第一个开始
for(j=strlen(s1)-1;j>=0;j--)
{
tmp=0;
if(s1[k]==s1[j])
{
tmp++;
k++;
j--;
while(k<strlen(s1)&&j>=0&&s1[k]==s1[j])
{
tmp++;
k++;
j--;
}
if(tmp>max){
max=tmp;
}
}
}
}
printf("%d\n",max);
return 0;
}
希望这周六一切顺利,加油。