zoukankan      html  css  js  c++  java
  • 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;
    }

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

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

  • 相关阅读:
    Hdu3022 Sum of Digits
    bzoj3864 Hero meet devil
    bzoj2448 挖油
    poj3783 Balls
    bzoj3802 Vocabulary
    Hdu5181 numbers
    Hdu5693 D Game
    图形填充之边标志算法
    图形填充之栅栏填充算法
    图形填充之种子填充算法
  • 原文地址:https://www.cnblogs.com/ay27/p/2713229.html
Copyright © 2011-2022 走看看