zoukankan      html  css  js  c++  java
  • csu-1328 近似回文词 和 最长回文字符串

    原博文地址:http://blog.csdn.net/u012773338/article/details/39857997

    最长回文子串

    描述:输入一个字符串,求出其中最长的回文子串。子串的含义是:在原串连续出现的字符 串片段。回文的含义是:正着看和倒着看是相同的,如abba和abbebba。在判断是要求忽略所有的标点和空格,且忽略大小写,但输出时按原样输出(首 尾不要输出多余的字符串)。输入字符串长度大于等于1小于等于5000,且单独占一行(如果有多组答案,输出第一组)。

    输入 :每行有一个字符串。

    输出 :输出所要求的回文子串。

    样例输入:    Confuciuss say:Madam,I'm Adam.

    样例输出  :  Madam,I'm Adam

     

    思路:

    1,用gets或者fgets读入完整的一行,

    2,预处理构造一个新的字符串,不包含原来的标点符号,并且把所有字母变成大写。用s数组保存。

    3,枚举每个回文串的中间位置i,然后不断向外扩展,直到有字符不同,但是长度为奇数和偶数的处理方式是不一样的,比如aba,abba。

    回文串为奇数时,从第i个向左(i-j)向后(i+j)遍历,为偶数时,从第i个向左(i-j)向右(i+j+1)遍历。不想等就退出。

    4,不断更新最大回文串长度,并且用一个数组p保存最大回文串在原串的起始位置和结束位置。

    代码:

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<ctype.h>
     4 #define MAXN 5000 + 10
     5 char buf[MAXN], s[MAXN];
     6 int p[MAXN];
     7 int main()
     8 {
     9     int n,m=0,maxn=0,x,y,i,j;
    10     fgets(buf,sizeof(s),stdin);//s肯定是一个字符数组。该调用从标准输入流stdin(也就是键盘输入)
    11     n=strlen(buf);            //读入 s 数组的大小(sizeof(s))再减 1 的长度的字符到 buf 所指的内存空间中(前提是buf已经申请好空间了)
    12     for(i=0;i<n;i++)
    13     {
    14         if(isalpha(buf[i])) //判断字符i是否是字母用到了isalpha这个函数
    15         {
    16             p[m]=i;     //把字母在原串的初始位置保存
    17             s[m++]=toupper(buf[i]); //转化成大写字母用s数组保存
    18         }
    19     }
    20     for(i=0;i<m;i++)
    21     {
    22         for(j=0;i-j>=0&&i+j<m;j++) //枚举奇数的回文串 注意下标的变换
    23         {
    24             if(s[i-j]!=s[i+j]) break;
    25             if(j*2+1>maxn) {maxn=j*2+1;x=p[i-j];y=p[i+j];}  //回文串的长度为2*j+1,比如aba,记录起始位置和终止位置
    26         }
    27         for(j=0;i-j>=0&&i+j+1<m;j++) //枚举偶数的回文串
    28         {
    29             if(s[i-j]!=s[i+j+1])break;
    30             if(j*2+2>maxn) {maxn=j*2+2;x=p[i-j];y=p[i+j+1];} //长度为2*j+2,比如abba,
    31         }
    32     }
    33     for(i=x;i<=y;i++)
    34         printf("%c",buf[i]); //输出最长回文串
    35     printf("
    ");
    36     return 0;
    37 }
    

    csu-1328 近似回文词

    1328: 近似回文词

    Time Limit: 1 Sec  Memory Limit: 128 MB
    Submit: 312  Solved: 118
    [Submit][Status][Web Board]

    Description

    输入一行文本,输出最长近似回文词连续子串。所谓近似回文词是指满足以下条件的字符串:

    1. S以字母开头,字母结尾

    2. a(S)和b(S)最多有2k个位置不同,其中a(S)是S删除所有非字母字符并且把所有字母转化成小写之后得到的串,b(S)是a(S)的逆序串。

    比如当k=1时,Race cat是一个近似回文词,因为a(S)=racecat和b(S)=tacecar只有2个位置不同。

    Input

    输入包含不超过25组数据,每组数据包含两行。第一行是整数k(0<=k<=200),第二行为字符串S,包含至少一个字母但不超过1000个字符(换行符不算)。S只包含字符、空格和其他可打印字符(比如逗号,句号),并且不会以空白字符开头。

    Output

    对于每组测试数据,输出最长近似回文子串的长度和起始位置(S的第一个字符是位置1)。如果有多个最长近似回文子串解,起始位置应尽量小。

    Sample Input

    1
    Wow, it is a Race cat!
    0
    abcdefg
    0
    Kitty: Madam, I'm adam.
    

    Sample Output

    Case 1: 8 3
    Case 2: 1 1
    Case 3: 15 8
    

    HINT

     

    Source

    [Submit][Status][Web Board]

    跟上题的区别在于这里可以有2*k个字符不同,那处理的时候只要另外设置一个标志变量ans,当ans>k 就跳出即可,还要注意一些细节的处理,特别是枚举偶数的近似回文串的时候,如果j==0即没有满足题目条件的近似回文串,那么应该不能更新最大值,因为 ab不是回文串,最大长度只能是1。其他的就是一样。

    代码:

    #include<stdio.h>
    #include<string.h>
    #include<ctype.h>
    #define MAXN 1000 + 10
    char buf[MAXN], s[MAXN];
    int p[MAXN];
    int main()
    {
        int k,n,m,maxn,x,y,i,j,l=1,cas,start;
        while(scanf("%d",&k)!=EOF)
        {
            getchar();
            fgets(buf,sizeof(s),stdin);//s肯定是一个字符数组。该调用从标准输入流stdin(也就是键盘输入)
            n=strlen(buf);
            m=maxn=0;
            start=-1;        //读入 s 数组的大小(sizeof(s))再减 1 的长度的字符到 buf 所指的内存空间中(前提是buf已经申请好空间了)
            for(i=0;i<n;i++)
            {
                if(isalpha(buf[i])) //判断字符i是否是字母用到了isalpha这个函数
                {
                    p[m]=i;     //把字母在原串的初始位置保存
                    s[m++]=tolower(buf[i]); //转化成大写字母用s数组保存
                }
            }
            //s[m]=0;
            for(i=0;i<m;i++)
            {
                for(cas=j=0;i-j>=0&&i+j<m;j++) //枚举奇数的近似回文串
                {
                    if(s[i-j]!=s[i+j]) cas++;
                    if(cas>k) break;
                }
                j--;
                if(p[i+j]-p[i-j]+1>maxn) {maxn=p[i+j]-p[i-j]+1; start=p[i-j];}
                for(cas=j=0;i-j>=0&&i+j+1<m;j++) //枚举偶数的近似回文串
                {
                    if(s[i-j]!=s[i+j+1])cas++;
                    if(cas>k) break;
                }
                j--;
                if(j<=-1) continue;
                if(p[i+j+1]-p[i-j]+1>maxn) {maxn=p[i+j+1]-p[i-j]+1; start=p[i-j];}
            }
            printf("Case %d: %d %d
    ",l++,maxn,start+1);
     
        }
        return 0;
    }
  • 相关阅读:
    Selenium Webdriver 自动化测试开发常见问题(C#版)VS
    HTML 和 Body 在 CSS 中的区别
    安装SDK时出现Fetching https://dl-ssl.google.com/android/repository/addons_list-1.xml
    配置好Java和SDK的环境变量后,Javac不是内部命令
    关于adb连接手机offline的问题解决
    CSDN上总结的测试工具排名
    关于性能优化
    关于WAS_1
    IIS服务器搭建
    关于WAS
  • 原文地址:https://www.cnblogs.com/lovychen/p/4458448.html
Copyright © 2011-2022 走看看