zoukankan      html  css  js  c++  java
  • 【u230】回文词

    Time Limit: 1 second
    Memory Limit: 128 MB

    【问题描述】

    CR喜欢研究回文词,有天他发现一篇文章,里面有很多回文数,这使他来了兴趣。他决定找出所有长度在n个字节以上的回文数。
    在寻找回文时不用理睬那些标点符号、空格(但应该保留下来以便作为答案输出),只用考虑英文字母’A’—’Z’和’a’—’z’。
    要你寻找的回文的文章是一个不超过5,000个字符的字符串。

    【输入格式】

    第一行为要找的回文的长度n。后面一行或几行为一个不超过5,000个字符的字符串。

    【输出格式】

    输出的最后一行为找到的长度大于等于n的回文词的个数。同一个回文中心只算一组回文,并且输出这组回文最长的回文。 前面一行或几行应该包括所有长度大于等于n的回文词的原文(没有除去标点符号、空格),把这些回文输出到一行或多行(如果回文中包括换行符)。 如果有多个回文长度大于等于n,全部输出所有回文。按回文中心在原文中的出现顺序依次输出。

    【数据规模】

    对于40%的数据: 在2000个字符以内 对于l00%的数据: 在5000个字符以内

    Sample Input1

    3
    Confucius say:Madam,I’m Adam.

    Sample Output1

    Madam
    Madam,I’m Adam
    m Adam
    3

    【题目链接】:http://noi.qz5z.com/viewtask.asp?id=u230

    【题解】

    直接枚举就可以了;(我一直以为O(N^2)的算法会超);
    枚举回文词的中心;
    注意有两种情况
    ABCBA

    ABCCBA
    即有的回文没有回文中心;
    枚举回文的长度j;
    不断判断s[i-j]和s[i+j]是否相等即可;
    这题文件要一直读到底(有多行的输入、换行也要读(最后的输出读入的换行符号也要输出..)
    while (scanf(“%c”,key)!=EOF) s+=c;
    把字母隔离出来(全都转成小写字母判断相同即可);

    【完整代码】

    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <set>
    #include <map>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    #include <vector>
    #include <stack>
    #include <string>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define LL long long
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i >= b;i--)
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pll;
    
    void rel(LL &r)
    {
        r = 0;
        char t = getchar();
        while (!isdigit(t) && t!='-') t = getchar();
        LL sign = 1;
        if (t == '-')sign = -1;
        while (!isdigit(t)) t = getchar();
        while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
        r = r*sign;
    }
    
    void rei(int &r)
    {
        r = 0;
        char t = getchar();
        while (!isdigit(t)&&t!='-') t = getchar();
        int sign = 1;
        if (t == '-')sign = -1;
        while (!isdigit(t)) t = getchar();
        while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
        r = r*sign;
    }
    
    const int MAXN = 5500;
    const int dx[5] = {0,1,-1,0,0};
    const int dy[5] = {0,0,0,-1,1};
    const double pi = acos(-1.0);
    
    int n;
    string s;
    vector <int> a;
    int lens;
    
    void pri(int l,int r)
    {
        rep1(i,a[l],a[r])
            cout << s[i];
        puts("");
    }
    
    bool xd(char x,char y)
    {
        char tx = x,ty =y;
        if ('A'<=x&&x<='Z')
            tx='a'+x-'A';
        if ('A'<=y&&y<='Z')
            ty='a'+y-'A';
        return tx==ty;
    }
    
    int main()
    {
        //freopen("F:\rush.txt","r",stdin);
        cin>>n;
        getchar();
        s=" ";
        char key;
        while (scanf("%c",&key)!=EOF)
            s+=key;
        lens = s.size()-1;
        rep1(i,1,lens)
            if (isalpha(s[i]))
                a.pb(i);
        int len = a.size();
        int ans = 0;
        rep1(i,0,len-1)
        {
            int j = 0;
            while (i-j>=0 && i+j<=len-1 && xd(s[a[i-j]],s[a[i+j]]))
                j++;
            if (((j-1)*2+1)>=n)
            {
                pri(i-j+1,i+j-1);
                ans++;
            }
            if (i-1>=0 && xd(s[a[i-1]],s[a[i]]))
            {
                int j = 1;
                while (i-j>=0 && i-1+j<=len-1 && xd(s[a[i-j]],s[a[i-1+j]]))
                    j++;
                if (((j-1)*2)>=n)
                {
                    pri(i-j+1,i+j-2);
                    ans++;
                }
            }
        }
        cout << ans << endl;
        return 0;
    }
    
  • 相关阅读:
    c++获取线程id
    一个基于c++的log库
    防止socket程序重启等待2MSL时间
    c++头文件循环引用
    Myeclipse 8.5 优化设置
    来道题 求解释
    MyEclipse常用设置笔记
    Ubuntu 学习笔记
    Linux 下常用命令
    Oracle 学习笔记 常用查询命令篇
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626937.html
Copyright © 2011-2022 走看看