/* ID: aznfy1 PROG: calfflac LANG: C++ */ #include<stdio.h> #include<string.h> #include<iostream> #include<ctype.h> #include<math.h> using namespace std; char source[20001]={0}; char cr[20001]={0}; char line[81]; int maxlen;int u,v; int maxu;int maxv; int main() { freopen("calfflac.in","r",stdin); freopen("calfflac.out","w",stdout); while(gets(line)!=NULL) { strcat(source,line); cr[strlen(source)-1]=1; } int len2=strlen(source); for(int i=0;i<len2;i++) { if(!isalpha(source[i])) continue; u=v=i;int len=-1; while(v>=0&&(u<=(len2-1))) { if((source[u]!=source[v])&&(fabs(source[u]-source[v])!=32)) break; len+=2; if(len>maxlen) { maxlen=len; maxu=u; maxv=v; } u++;v--; while((u<=(len2-1))&&!isalpha(source[u])) u++; while(v>=0&&!isalpha(source[v])) v--; } u=i+1;v=i;len=0; while(v>=0&&(u<=(len2-1))) { if((source[u]!=source[v])&&(fabs(source[u]-source[v])!=32)) break; len+=2; if(len>maxlen) { maxlen=len; maxu=u; maxv=v; } u++;v--; while((u<=(len2-1))&&!isalpha(source[u])) u++; while(v>=0&&!isalpha(source[v])) v--; } } printf("%d\n",maxlen); for(int i=maxv;i<=maxu;i++) { printf("%c",source[i]); if(cr[i]==1) printf("\n"); } if(cr[maxu]!=1) printf("\n"); return 0; }
这道题出现了一点问题,刚开始没有写 len2=strlen(source) 导致第八组数据卡住1.6S,因为每次用到这个长度都扫描计算一次,实在太菜,以后不能再犯了。
大体思路:
#1.输入:一行一行的输入,每行cat进大数组中,并且记录好该换行的位置,因为输出时需要考虑在哪里输出换行符。
#2.主程序:从第一位扫描到串尾,假设它是回文串的中心字符,并向两边进行扩展,需要进行总的两次扫描,一次为奇串,一次为偶串。
扫描中注意以下几点:
1.不是字母继续下一位枚举
2.向两边搜索,两个字符字符相等或者互为大小写,则更新为最长子串,否则BREAK,
3.搜索时,遇到!isalpha应当跳过不管,只看字符,不看符号。
#3:输出:原样输出,注意输出换行符。
附上HL神牛的论文
还没看完