USACOCalf Flac

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;
}

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

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

原文地址:https://www.cnblogs.com/ay27/p/2713229.html