zoukankan      html  css  js  c++  java
  • csuoj 1328: 近似回文词

    http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1328

    1328: 近似回文词

    Time Limit: 1 Sec  Memory Limit: 128 MB

    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

    湖南省第九届大学生计算机程序设计竞赛


    分析:

    暴力模拟(有人说会有TLE,但是我就AC啦,RP吧)即可, 还可以从某个点往两边分别比较。

    AC代码:

     1 #include <stdio.h>
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <string.h>
     5 #include <string>
     6 #include <math.h>
     7 #include <stdlib.h>
     8 #include <queue>
     9 #include <stack>
    10 #include <set>
    11 #include <map>
    12 #include <list>
    13 #include <iomanip>
    14 #include <vector>
    15 #pragma comment(linker, "/STACK:1024000000,1024000000")
    16 #pragma warning(disable:4786)
    17 
    18 using namespace std;
    19 
    20 const int INF = 0x3f3f3f3f;
    21 const int MAX = 2000 + 10;
    22 const double eps = 1e-8;
    23 const double PI = acos(-1.0);
    24 
    25 char str[MAX] , hw[MAX];
    26 int chang[MAX];
    27 int k;
    28 
    29 int main()
    30 {
    31     int cas = 1;
    32     while(~scanf("%d",&k))
    33     {
    34         getchar();
    35         gets(str);
    36         int len = strlen(str);
    37         int cnt = 0;
    38         for(int i = 0 ;i < len;i ++)
    39         {
    40             if((str[i] >= 'A' && str[i] <= 'Z') || (str[i] >= 'a' && str[i] <= 'z'))
    41             {
    42                 char c = str[i];
    43                 if(c >= 'A' && c <= 'Z')
    44                     c = c - 'A' + 'a';
    45                 chang[cnt] = i;
    46                 hw[cnt ++] = c;
    47             }
    48         }
    49         hw[cnt] = '';
    50         int maxlen = 1 , pos = 1;
    51         for(int j = cnt;j >= 1;j --)
    52             for(int i = 0;i + j - 1 < cnt;i ++)
    53             {
    54                 int st = i + j - 1,cnt = 0;
    55                 int len = chang[st] - chang[i] + 1;
    56                 if(len < maxlen)
    57                     continue;
    58                 for(int l1 = i,l2 = st;l1 < l2;l1 ++ , l2 --)
    59                 {
    60                     if(hw[l1] != hw[l2])
    61                         cnt += 2;
    62                     if(cnt > 2 * k)
    63                         break;
    64                 }
    65                 if(cnt <= 2 * k)
    66                 {
    67                     if(maxlen < len || (maxlen == len && i < pos))
    68                     {
    69                         maxlen = len;
    70                         pos = i;
    71                     }
    72                 }
    73             }
    74         printf("Case %d: %d %d
    ",cas ++ , maxlen , chang[pos] + 1);
    75     }
    76     return 0;
    77 }
    View Code

    这个是用往两边扩展写的,不会存在超时!!!

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<queue>
     6 #include<string>
     7 #include<cmath>
     8 #include<cctype>
     9 using namespace std;
    10 char s[1010],s1[1010];
    11 int ans[1010];
    12 int main()
    13 {
    14     int T=1,k,i,j;
    15     while(~scanf("%d",&k))
    16     {
    17        int a = 0,kk=0,start = 0,flag;
    18        getchar();
    19        gets(s);
    20        int len = strlen(s);
    21        for( i=0;i<len;i++)
    22        {
    23            if(isalpha(s[i])) //判断是否是字母
    24            {
    25                ans[kk] = i;
    26                s1[kk] = toupper(s[i]);//转换成大写字母
    27                kk++;
    28            }
    29        }
    30        for( i=0; i<kk; i++)
    31        {
    32             flag = 0;
    33             for( j=0;i-j>=0 && i+j<kk; j++)//奇数个时;
    34             {
    35                 if(s1[i-j]!=s1[i+j])
    36                     flag++;
    37                 if(flag>k)
    38                     break;
    39             }
    40             j--;
    41             if(ans[i+j]-ans[i-j]+1>a)
    42             {
    43                 a = ans[i+j]-ans[i-j]+1;
    44                 start = ans[i-j];
    45             }
    46             flag  = 0;
    47             for( j=0; i-j>=0 && i+j+1<kk; j++)//偶数个时
    48             {
    49                     if(s1[i-j]!=s1[i+j+1])
    50                         flag ++;
    51                     if(flag>k)
    52                         break;
    53             }
    54             j--;
    55             if(j<=-1)
    56                 continue;
    57             if(ans[i+j+1]-ans[i-j]+1>a)
    58             {
    59                 a = ans[i+j+1]-ans[i-j]+1;
    60                 start = ans[i-j];
    61             }
    62        }
    63        printf("Case %d: %d %d
    ",T++,a,start+1);
    64     }
    65   return 0;
    66 }
    View Code
  • 相关阅读:
    Vue自定义指令 directive
    Vue过滤器 filters
    贪心
    家庭作业
    线段
    数列极差
    shell
    智力大冲浪
    加工生产调度
    喷水装置
  • 原文地址:https://www.cnblogs.com/jeff-wgc/p/4458509.html
Copyright © 2011-2022 走看看