噩梦多校6,HDU6103 Kirinriki
Problem Description
We define the distance of two strings A and B with same length n is
disA,B=
∑k1
|Ai−Bn−1−i| (k=n-1)
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是他的子串,AB长度相等且AB没有重叠,求满足disA,B<=m的最小长度。
这题其实不难,比赛的时候已经想到枚举对称中心了,可是没想到用尺取法来取,还是练的少,脑子不好。AB对称中心有两种,一种是以一个字符对称,另一种是以一个空位对称
下面是我看过题解后的ac代码
#include<iostream>
#include<cstdio>
#include<string.h>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;
int n,m,T,ans;
string s;
int k;
int getans()
{
int len=s.length();
int sum,ans=0;
for(int i=0;i<len;i++) //对称中心是字符
{ sum=0;
for(int l=i,r=i,pl=l,pr=r;l>=0&&r<len;l--,r++)
{
sum+=abs(s[r]-s[l]);
while(sum>m&&pr<=r) sum-=abs(s[pr++]-s[pl--]);
ans=max(ans,r-pr+(pr!=i));
}
}
for(int i=1;i<len;i++) //对称中心是空位
{
sum=0;
for(int l=i-1,r=i,pl=l,pr=r;l>=0&&r<len;l--,r++)
{
sum+=abs(s[r]-s[l]);
while(sum>m&&pr<=r) sum-=abs(s[pr++]-s[pl--]);
ans=max(ans,r-pr+1);
}
}return ans;
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d",&m);
cin>>s;
printf("%d\n",getans());
}
}