USACO Calf Flac

郁闷死我了,求最长的回文串;

本身读进来的是含有标点符号的一个文本串,之后找回文串的时候又忽略了那些标点符号,输出又要将那些标点符号输出…………

蛋疼好久,幸好是可以看到什么例子没过,不过,我看是没希望过的了…………

orz,文本里面的“\n”也是有效的……

用前面的那个求最长回文串的算法就很容易过了,主要是 在处理那个标点符号的问题上……

/*
ID: nanke691
LANG: C++
TASK: calfflac
*/
#include<iostream>
#include<fstream>
#include<string.h>
#define maxn 20010
using namespace std;
char str1[maxn],str2[maxn*2];
int n,l1,mid,len;
int nxt[maxn*2];
void Manacher ()
{
	int mx=0,id;
	len=-1;
	memset(nxt,0,sizeof(nxt));
	for(int i=1;i<l1;i++)
	{
		if(mx>i)
			nxt[i]=min(nxt[2*id-i],mx-i);
		else nxt[i]=1;
		for(;str2[i-nxt[i]]==str2[i+nxt[i]];nxt[i]++);
		if(mx<i+nxt[i])
		{
			mx=i+nxt[i];
			id=i;
		}
		if(len<nxt[i]-1)
		{
			len=nxt[i]-1;
			mid=i;
		}
	}
}
void pre()
{
	str2[0]='$';
	int i=0,t=0,k=1;
	while(str1[i]!='\0')
	{
		if(t)
		{
			int flag=0;
			while(1)
			{
				if((str1[i]>='A'&&str1[i]<='Z')|| (str1[i]>='a'&&str1[i]<='z'))
					break;
				if(str1[i]=='\0')
				{
					flag=1;break;
				}
				i++;
			}
			if(flag)
				break;
		str2[k++]=str1[i++];
		}
		else str2[k++]='#';
		if(str2[k-1]>='A'&&str2[k-1]<='Z')
			str2[k-1]+=32;
		t^=1;
	}
	str2[k++]='#';
	str2[k]='\0';
	l1=k;
}
void  print(int s)
{
	int count=0,flag=0;
	for(int i=s;str1[i]!='\0';i++)
	{

		if((str1[i]>='A'&&str1[i]<='Z')|| (str1[i]>='a'&&str1[i]<='z'))
			count++;
		printf("%c",str1[i]);	
		if(count==len)
			break;
	}
	printf("\n");
}
int main()
{
	freopen("calfflac.in","r",stdin);
	freopen("calfflac.out","w",stdout);
	char str[maxn];
	while(gets(str))
	{
		strcat(str1,"\n");
		strcat(str1,str);
	}
		pre();
		//printf("%s\n",str2);
		Manacher();
		printf("%d\n",len);
		int count=0,s=(mid-len)/2+1;
		for(int i=0;str1[i]!='\0';i++)
		{
			if((str1[i]>='A'&&str1[i]<='Z')|| (str1[i]>='a'&&str1[i]<='z'))
				count++;
			if(count==s)
			{
				print(i);
				break;
			}
		}
	return 0;
}


原文地址:https://www.cnblogs.com/nanke/p/2213441.html