您的位置:首页 > 其它

-----尺取法 hdu 6103-Kirinriki

2017-08-12 10:35 375 查看
Problem Description

We define the distance of two strings A and B with same length n is

disA,B=∑i=0n−1|Ai−Bn−1−i|

The difference between the two characters is defined as the difference in ASCII.

You should find the maximum length of two non-overlapping substrings in given string S, and the distance between them are less then or equal to m.

Input

The first line of the input gives the number of test cases T; T test cases follow.

Each case begins with one line with one integers m : the limit distance of substring.

Then a string S follow.

Limits

T≤100

0≤m≤5000

Each character in the string is lowercase letter, 2≤|S|≤5000

∑|S|≤20000

Output

For each test case output one interge denotes the answer : the maximum length of the substring.

Sample Input

1

5

abcdefedcb

Sample Output

5

Hint

[0, 4] abcde

[5, 9] fedcb

The distance between them is abs(‘a’ - ‘b’) + abs(‘b’ - ‘c’) + abs(‘c’ - ‘d’) + abs(‘d’ - ‘e’) + abs(‘e’ - ‘f’) = 5

题目大意:

我们定义两个具有相同长度的串A和串B的距离为

,在一个长串中选两个不相交等长的子串A,B,使得两串的距离小于等于m,求子串的最大长度


解题思路:

枚举中心对称轴,因为有奇数串和偶数串两种情况,所以枚举中心对称轴的时候也要分奇偶两种情况

(1),奇数串(枚举的子串长度为j)



(2),偶数串(枚举的子串长度为j)



num[]数组存的是,每次枚举中心对称轴后的两个子串的差,然后在对差区间进行尺取,取最大长度;

样例模拟:



只模拟对称轴i=5,子串长度j=5的时候:

num[0]=a-b=1;

num[1]=b-c=1;

num[2]=c-d=1;

num[3]=d-e=1;

num[4]=e-f=1;

然后在 1,1,1,1,1 这个数字串利用尺取法选取子串,使得子串和<=m,且子串取最大长度;

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdlib>
using namespace std;

int m;
char str[5005];
int num[5005];

int chiqu(int len)///该长度下的串内进行尺取
{
int s=0,t=0,sum=0,maxlen1=0;///初始化起点终点为0,串的和为0
while(1)
{
while(sum+num[t]<=m&&t<len)
{
sum+=num[t];
maxlen1=max(maxlen1,(t-s+1));
t++;
}
sum-=num[s];
s++;
if(s>=len) break;
}
return maxlen1;
}

int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int maxlen=0;
scanf("%d",&m);
scanf("%s",str);
int len=strlen(str);
for(int i=0; i<len; i++) ///枚举偶数串的对称轴
{
int coun=0;///记录子串的长度
for(int j=1; i-j>=0&&i+j-1<len; j++)
num[coun++]=abs(str[i-j]-str[i+j-1]);///num[i]存的是两子串的距离

9e79
maxlen=max(maxlen,chiqu(coun));
}
for(int i=0; i<len; i++) ///枚举奇数串的对称轴
{
int coun=0;///记录子串的长度
for(int j=1; i-j>=0&&i+j<len; j++) ///枚举子串的长度
num[coun++]=abs(str[i-j]-str[i+j]);///num[i]存的是两子串的距离
maxlen=max(maxlen,chiqu(coun));
}
printf("%d\n",maxlen);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: