【注意getline吃空格】第三届ACM/ICPC程序设计知识竞赛—— 又见回文

来源:点击打开链接

求十万个字符以内的回文串,可以采用上一篇中的manacher算法,另外要判断空格,把无关的空格去掉。

按这个思路,WA了两次,原因是getchar()的时候会把第一个样例的第一个字符给吃掉,但如果不加,需要按两下回车才有结果,与题目不符,只能动手判断一下了。。

 

// 原串最大长度N

// 返回最大回文字串 res

#include <cstdio>

#include <cstring>

#include <cstdlib>

#include <string>

#include <algorithm>

#include <iostream>

#include <ctype.h>

using namespace std;

const int N = 200009;



int rid[N<<2];



string clear_space(string s)

{

	string res;

	for(int i=0;i<s.length();i++)

	{

		if(isblank(s[i]))

		{

			continue;

		}

		else if(isupper(s[i]))

		{

			res+=s[i]+32;

		}

		else if(islower(s[i]))

		{

			res+=s[i];

		}

		

	}

	return res;

}





string manacher(string s){

    string t, res;    

    int L = s.size();    

    // init

    t += '?';

    for(int i = 0; i < L; i++)

        t += '#', t += s[i];

    t += "#*";

    // getrid

    for(int i=1,j=0,k,End=(int)t.size();i<End;){

        while( t[i-j-1]==t[i+j+1] ) j++;

        rid[i] = j;

        for(k=1;k<=j&&(rid[i-k]!=rid[i]-k);k++) 

            rid[i+k] = min( rid[i-k], rid[i]-k );

        i += k;

        j = max( 0,j-k );

    }    

    // Max

    int m = 0, pos;

    for(int i = 1; i < (int)t.size(); i++){

        if( m < rid[i]*2+(t[i]!='#') )

            m = rid[i]*2+(t[i]!='#'), pos = i;

    }

    for(int i = pos-rid[pos]; i <= pos+rid[pos]; i++){

        if( t[i] != '#' ) res += t[i];    

    }

    return res;

}



int main()

{

	string tar;

	string res,ret;

	char z;

	int pos=0;

	z=getchar();  

	while(getline(cin,tar))

	{

		if(z!='\n' && pos==0)

		{

			tar.insert(tar.begin(),z);

			pos=1;

		}

		//cout<<tar<<endl;

		if(tar=="2013")

			break;

		ret=clear_space(tar);

		res=manacher(ret);

		if(res==ret || res==tar)

		{

			cout<<"YES"<<endl;

		}

		else

			cout<<"NO"<<endl;

		

	}

	

	

	return 0;

}


 

 

你可能感兴趣的:(程序设计)