zcmu--1616: 最长回文串(两种方法)

1616: 最长回文串

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 144  Solved: 113
[Submit][Status][Web Board]

Description

 求一个字符串的最长回文串

Input

 第一行输入n

接下来n行每行每行一个字符串长度<=100000

Output

 输出最长回文串的长度

Sample Input

3 abababa aaaabaa acacdas

Sample Output

7 5 3

HINT

不要想太多 Water

【分析】到最后才看到hint的“不要想太多Water”。。so!!!一般方法就好啦!!根本不用考虑效率的问题啊!!水题一道了。。

然后注意判断是否回文串的时候的下标s[i+j-k]:因为这段区间为i~j,中点为(i+j)/2,所以s[k]对应的点就是(i+j)/2-k+(i+j)/2=i+j-k啦~

#include<bits/stdc++.h>
using namespace std;
char s[100010];
int main()
{
	int n;
	scanf("%d",&n);
	while(n--)
	{
		memset(s,0,sizeof(s));
		scanf("%s",s);
		int len=strlen(s);
		int max=0;
		for(int i=0;i<len;i++)
			for(int j=i;j<len;j++)
			{
				int ok=1;
				for(int k=i;k<=j;k++)//套了3个循环还是木有超时hhh
					if(s[k]!=s[i+j-k])ok=0;
				if(ok&&j-i+1>max)max=j-i+1;//更新max
			}
		cout<<max<<endl;
	}
	return 0;
} 

方法二:枚举回文串的中间位置i,然后不断往外扩展直到有字符串不同。并且长度为奇数和偶数的方式有点区别的。

扫描二维码关注公众号,回复: 2795580 查看本文章

注释掉的部分是用于记录回文串开始和结束的地方。

#include<bits/stdc++.h>
using namespace std;
char s[100010];
int main()
{
	int n;
	scanf("%d",&n);
	while(n--)
	{
		memset(s,0,sizeof(s));
		scanf("%s",s);
		int len=strlen(s);
		int max=0;
		for(int i=0;i<len;i++)
		{	for(int j=0;i-j>=0&&i+j<len;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(int j=0;i-j>=0&&i+j+1<len;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];
				}
			}
		}cout<<max<<endl;
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/qq_38735931/article/details/81665148