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("\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;
}
时间: 2024-10-09 13:12:44

csu-1328 近似回文词 和 最长回文字符串的相关文章

csu 1328: 近似回文词

1328: 近似回文词 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 394  Solved: 144 [Submit][Status][Web Board] Description 输入一行文本,输出最长近似回文词连续子串.所谓近似回文词是指满足以下条件的字符串: 1. S以字母开头,字母结尾 2. a(S)和b(S)最多有2k个位置不同,其中a(S)是S删除所有非字母字符并且把所有字母转化成小写之后得到的串,b(S)是a(S)的逆序串. 比如

CSU 1328 近似回文词(2013湖南省程序设计竞赛A题)

题目链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1328 解题报告:中文题题意就不说了.还好数据不大,只有1000,枚举回文串的中心位置,然后向两边扩展,当扩展到 k 大于要求的K的时候停止扩展,不断更新最长的长度跟开始位置最小.我先做了个预处理,先求出了a(S),然后用一个数组保存了a(S)中的字符在原来的字符串中对应的位置在哪,这样便于字符串比较,而且又可以在O(1)时间得到在原来串中的长度跟开始的位置. 1 #include<cs

Vijos1327回文词

回文词 回文词是一种对称的字符串--也就是说,一个回文词,从左到右读和从右到左读得到的 结果是一样的.任意给定一个字符串,通过插入若干字符,都可以变成一个回文词.你的任务是写 一个程序,求出将给定字符串变成回文词所需插入的最少字符数. 比如字符串"Ab3bd",在插入两个字符后可以变成一个回文词("dAb3bAd"或"Adb3bdA"). 然而,插入两个以下的字符无法使它变成一个回文词. 输入格式: 文件的第一行包含一个整数N,表示给定的字符串的

【Vijos 1327】回文词(DP)

题目描述 回文词是一种对称的字符串——也就是说,一个回文词,从左到右读和从右到左读得到的结果是一样的.任意给定一个字符串,通过插入若干字符,都可以变成一个回文词.你的任务是写一个程序,求出将给定字符串变成回文词所需插入的最少字符数.   比如字符串“Ab3bd”,在插入两个字符后可以变成一个回文词(“dAb3bAd”或“Adb3bdA”).然而,插入两个以下的字符无法使它变成一个回文词. 输入 第一行包含一个整数N,表示给定字符串的长度,3<=N<=5000   第二行是一个长度为N的字符串,

算法题--最长回文子串

题目描述 给定一个字符串 s,找到 s 中最长的回文子串.你可以假设?s 的最大长度为 1000. 示例 1: 输入: "babad" 输出: "bab" 注意: "aba" 也是一个有效答案. 示例 2: 输入: "cbbd" 输出: "bb" 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/longest-palindromic-substring

字符串 - 近似回文词 --- csu 1328

近似回文词 Problem's Link:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1328 Mean: 略. analyse: 直接暴力枚举每一个终点,然后枚举回文串的半径即可. Time complexity:O(n*m) Source code: // Memory Time // 1347K 0MS // by : Snarl_jsb // 2014-10-03-14.25 #include<algorithm> #include

csuoj 1328: 近似回文词

http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1328 1328: 近似回文词 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 355  Solved: 138 [Submit][Status][Web Board] Description 输入一行文本,输出最长近似回文词连续子串.所谓近似回文词是指满足以下条件的字符串: 1. S以字母开头,字母结尾 2. a(S)和b(S)最多有2k个位置不同

UVA 401 Palindromes(回文词)

 回文词 Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Practice UVA 401 Appoint description:  acmparand  (2013-07-07)Luke  (2014-01-20) System Crawler  (2015-05-10) Description A regular palindrome is a string of

UVa401 回文词

Palindromes A regular palindrome is a string of numbers or letters that is the same forward as backward. For example, the string "ABCDEDCBA" is a palindrome because it is the same when the string is read from left to right as when the string is