近似回文词

好久没写博客了。。。开学来了学校后总是烦于总结,最近看大家都开始写了,自己才又拾起来。。。

题目:

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

题意:

这题太像USACO上的那道CALF FLAC了,有一点区别就是他是说给你一个K,那么最长回文串中最多可以有2*k个位置的字母不同。所以叫做近似回文串。

思路:

这题似乎用USACO那题自己的思路有些复杂了,所以就用了那小白书上的方法,分为近似回文串奇数和偶数的情况来写。从中间往两侧找,发现很多字符串的题思路都是从中间往两侧找。这题又被空格坑了,我们oj测试数据输完k后居然又有空格,搞的我一直wa。。。。

代码:

#include<stdio.h>
#include<string.h>
int main()
{
    int k,n,p[1000],j,i,o,l=0;
    char str[1000],ch[1000];
    while (scanf("%d",&k)!=EOF)
    {
        l++;
        int max=0,f=0,t=0;
        gets(str);//输入k后的空格。。。。
    gets(str);
    n=strlen(str);
    int m=0;
    for ( i=0;i<n;i++)
    {
        if (str[i]>='a'&&str[i]<='z'){
            p[m]=i+1;//记录下字母在原字符串中的位置,以便最后输出。
             ch[m++]=str[i];
        }
        if (str[i]>='A'&&str[i]<='Z'){
            p[m]=i+1;
            ch[m++]=str[i]-'A'+'a';
        }//将字母存起来,并统一转换为大写或小写。
    }
    f=0;
    for (i=0;i<m;i++){
            o=k;
        for (j=0;i-j>=0&&i+j<m;j++){
            if (ch[i-j]!=ch[i+j])
                o--;//若有一组不同了,就给k--;
                if (o<0)
                     break;
                     t=p[i+j]-p[i-j]+1;
                     if (t>max){
                        max=t;
                        f=p[i-j];
                     }
            }//若以当前字母为中心回文串为奇数的时候
        o=k;
        for (j=0;i-j>=0&&i+j+1<m;j++){
            if (ch[i-j]!=ch[i+j+1])
                o--;
                if (o<0)
                    break;
                 t=p[i+j+1]-p[i-j]+1;
                    if (t>max){
                    max=t;
                    f=p[i-j];
                }//若以当前字母为中心回文串为偶数的时候
        }
    }
        printf("Case %d: %d %d\n",l,max,f);
    }
    return 0;
}

注:

刚开始的时候就是认为是n后有个空格却没想太多,突然想起来为何我刚开始用getchar会出错,去搜了一下,才发现了问题,原来getchar在读入字符时以回车结束可是却 不会舍弃回车,会把回车保留在缓冲区,所以,在用getchar的时候读到的字符串的第一个字符就成了回车,而gets读入字符串是也是以回车结束,可是他会舍弃回车,这样读到的第一个字符才是我们输入的。

所以如果一组测试数据后有个空格然后再是回车的话,用scanf(“\n”);和getchar();是不同的,第一种读入了一个空,而第二种则读入了两个空。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值