来源:点击打开链接
求十万个字符以内的回文串,可以采用上一篇中的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; }