码迷,mamicode.com
首页 > 其他好文 > 详细

csu-1328 近似回文词 和 最长回文字符串

时间:2015-04-26 22:43:50      阅读:169      评论:0      收藏:0      [点我收藏+]

标签:

原博文地址: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("\n");
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\n",l++,maxn,start+1);
 
    }
    return 0;
}

 

csu-1328 近似回文词 和 最长回文字符串

标签:

原文地址:http://www.cnblogs.com/lovychen/p/4458448.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!