USACO-Calf Flac

来源:互联网 发布:网络教育英语b统考 编辑:程序博客网 时间:2024/06/06 11:36

http://ace.delos.com/usacoprob2?a=I1dC0kaErvZ&S=calfflac

求文章的最大回文字串,暴搜就可以了。可以算一下时间复杂度,O()=20000*2000=40000000,四千万而已,绝对不超时,当然前提是不用string,若用string,可能会超时,这个我没有试过了。

主要是枚举回文串的中值,然后用两个指针向中值的两边尽可能扩展,然后记录最大的长度就行了。网上的解题报告更多的是用两个数组工作,这个当然也是一个好方法,但是输出时是个麻烦。所以我直接用一个数组,在扩展时判断是否为字母,而输出时就简单很多了。

#include <iostream>#include <string.h>#include <string>#include <cstdio>#include <ctype.h>    //isalpha函数的定义头文件using namespace std;char s[30000];void search(int len,int &sum,int &ll,int &rr){    while (ll>0 && rr<len)            //指针的移动必须在文章中,不可超出范围了    {        while (ll>0 && !isalpha(s[ll])) ll--;        while (rr<len && !isalpha(s[rr])) rr++;        if (s[ll]==s[rr] || (s[ll]-'a'+'A')==s[rr] || (s[ll]-'A'+'a'==s[rr]))        {            sum+=2;            ll--; rr++;        }        else return;       //若二者不相等,明显回文到此结束    }}int main(){    freopen("calfflac.in","r",stdin);    freopen("calfflac.out","w",stdout);    int len=0;    char ss[30000];    while (gets(ss))    {        if (len)            s[++len]='\n';        for (int i=0;ss[i];i++)            s[++len]=ss[i];    }    s[++len]='\0';    int max=0,start=0,endd=0;    for (int i=1;i<=len;i++)    if (isalpha(s[i]))    {        //处理回文串长度是偶数的情况        int even=0;                int l=i-1,r=i+1;        while (l>0 && !isalpha(s[l])) l--;        while (r<len && !isalpha(s[r])) r++;        if (s[l]==s[i] || (s[l]-'a'+'A')==s[i] || (s[l]-'A'+'a'==s[i]))        {            even=2;            l--;            search(len,even,l,r);            if (even>max)            {                max=even;                start=l+1; endd=r-1;            }        }        else if (s[r]==s[i] || (s[r]-'a'+'A')==s[i] || (s[r]-'A'+'a'==s[i]))        {            even=2;            r++;            search(len,even,l,r);            if (even>max)            {                max=even;                start=l+1; endd=r-1;            }        }        //处理奇数情况        l=i-1; r=i+1;        int odd=1;        search(len,odd,l,r);        if (odd>max)        {            max=odd;            start=l+1; endd=r-1;        }    }    //因为之前记录时没有忽略非字母的字符,所以现在要修改一下    while (!isalpha(s[start])) start++;    while (!isalpha(s[endd])) endd--;    cout<<max<<endl;    for (int i=start;i<=endd;i++)        cout<<s[i];    cout<<endl;    return 0;}

当然,我的程序写得不怎样,太多重复的代码,但是如果改为函数,要传递的参数又过多,得不偿失了。

这题自己出数据太简单了,所以这题基本上要秒杀的。。。。