1328: 近似回文词
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 394 Solved: 144
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
1Wow, it is a Race cat!0abcdefg0Kitty: Madam, I‘m adam.
Sample Output
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); } }
时间: 2024-12-07 19:00:55