(预处理,初始化)近似回文词 Almost Palindrome,9th湖南省赛A

来源:互联网 发布:淘宝能卖药品吗 编辑:程序博客网 时间:2024/05/16 17:56

1328: 近似回文词

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 182  Solved: 65
[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

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


作为"通过预处理能使程序更好写","注意作为答案的变量的初始化"水题代表在此留一席之地.
还有就是注意在xxx输入后用gets()输入字符串时用getchar()吃掉输入流缓冲区的'\n'.
代码:
#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <string>#include <algorithm>using namespace std;const int maxn = 1005;typedef long long LL;char a[maxn], b[maxn];int mark[maxn];int K;int LEN, STA;int len;bool ok(int pos){if (0 <= pos&&pos < len)return true;return false;}void init()//(初始化和 预处理 ){LEN = 1;STA = 1;//初始化为最坏情况len = strlen(a);/*预处理: 将输入数据中的有用信息整理(提取字母,字母小写化,记录每个字母原来的位置)*/int top = 0;for (int i = 0; i < len; i++)if (isalpha(a[i])){b[top] = tolower(a[i]);mark[top] = i;top++;}b[top] = '\0';len = top;}void solve(){for (int p = 0; p < len; p++)//分两种情况对应枚举中间或中偏左位置{int l, r;int cnt = 1, k = 0;for (l = p - 1, r = p + 1; ok(l) && ok(r); l--, r++)//情况1,奇数个元素{if (b[l] == b[r])cnt = mark[r] - mark[l] + 1;else if (b[l] != b[r] && k < K){cnt = mark[r] - mark[l] + 1;k++;}elsebreak;if (LEN < cnt)//worst case为:K=0, a[]={"abcdefg"},LEN和STA并不能经过更新,故初始化时将LEN和STA初始化为最坏情况,即LEN=1,STA=1;{LEN = cnt;STA = mark[l] + 1;}}cnt = 0;k = 0;for (l = p, r = p + 1; ok(l) && ok(r); l--, r++)//情况2,偶数个元素{if (b[l] == b[r])cnt = mark[r] - mark[l] + 1;else if (b[l] != b[r] && k < K){cnt = mark[r] - mark[l] + 1;k++;}elsebreak;if (LEN < cnt){LEN = cnt;STA = mark[l] + 1;}}}}int main(){//freopen("f:\\input.txt", "r", stdin);int cas = 0;while (scanf("%d", &K) != EOF){getchar();gets(a);init();solve();printf("Case %d: %d %d\n", ++cas, LEN, STA);}return 0;}


0 0
原创粉丝点击