输入一行文本,输出最长近似回文词连续子串。所谓近似回文词是指满足以下条件的字符串:
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个位置不同。
输入包含不超过25组数据,每组数据包含两行。第一行是整数k(0<=k<=200),第二行为字符串S,包含至少一个字母但不超过1000个字符(换行符不算)。S只包含字符、空格和其他可打印字符(比如逗号,句号),并且不会以空白字符开头。
对于每组测试数据,输出最长近似回文子串的长度和起始位置(S的第一个字符是位置1)。如果有多个最长近似回文子串解,起始位置应尽量小。
1Wow, it is a Race cat!0abcdefg0Kitty: Madam, I‘m adam.
Case 1: 8 3Case 2: 1 1Case 3: 15 8
直接暴力枚举回文中心。
路过的知道为什么for(j=-1,k=1;j>=0,k<2;j--,k++);执行后j=-2,因为这个错了好多次。。
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<queue>
#include<map>
#include<vector>
#include<string>
#define ll long long
#define N 1110
using namespace std;
int n,m;
char s[N],s1[N];
int num[N];
int main() {
//freopen("in.txt","r",stdin);
int ca=1;
while(~scanf("%d",&m)) {
getchar();
gets(s);
int len=strlen(s);
int k=0;
for(int i=0; i<len; i++) {
if(s[i]>='A'&&s[i]<='Z') {
s1[k]=s[i]+32;
num[k++]=i;
} else if(s[i]>='a'&&s[i]<='z') {
s1[k]=s[i];
num[k++]=i;
}
}
s1[k]='\0';
int Max=1;
int l=0;
for(int i=0; i<k; i++) {
int w=m;
int j,jk;
for( j=i-1,jk=i+1; ; j--,jk++) {///以i为中心点
if(j<0||jk>=k)break; ///不知道为什么,这个放for()里,就错了,求告知
if(s1[j]!=s1[jk]&&w==0) {
break;
}
if(s1[j]!=s1[jk])
w--;
}
j++,jk--;
if(j<=jk) {
if(num[jk]-num[j]+1>Max) {
Max=num[jk]-num[j]+1;
l=num[j];
} else if(num[jk]-num[j]+1==Max) {
l=min(l,num[j]);
}
}
w=m;
for(j=i,jk=i+1; ; j--,jk++) {///以i和i+1中间为中心点
if(j<0||jk>=k)break;
if(s1[j]!=s1[jk]&&w==0) {
break;
}
if(s1[j]!=s1[jk])
w--;
}
j++,jk--;
if(j<=jk) {
if(num[jk]-num[j]+1>Max) {
Max=num[jk]-num[j]+1;
l=num[j];
} else if(num[jk]-num[j]+1==Max) {
l=min(l,num[j]);
}
}
}
printf("Case %d: %d %d\n",ca++,Max,l+1);
}
}
原文地址:http://blog.csdn.net/acm_baihuzi/article/details/45588777