HDU - 6103 :Kirinriki(不错的尺取法)

We define the distance of two strings A and B with same length n is
diA,=∑ i=n|n1disA,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.

InputThe 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
T100 T≤100
0m5000 0≤m≤5000
Each character in the string is lowercase letter, 2|S|5000 2≤|S|≤5000
|S|20000 ∑|S|≤20000
OutputFor 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

题意:给堵一个字符串,求最长的两个不相交字串S、T,其字符串值之差小于M,输出这个长度。

思路:尺取法,枚举起点终点发现没法做,我们枚举S和T的对称点,然后根据对称点尺取。即每次右边界++,维护左边界,使其满足小于M。

主要是利用了此题中,字符串之差是首尾倒序做差,我们我们可以这样处理。  有点像求回文串一样。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
char c[5050]; int T,N,M,ans;
void solve()
{
    rep(i,1,N){
        int L=1,R=0,tmp=0;
        while(i+R+1<=N&&i-R-1>=1){
            R++; tmp+=abs(c[i+R]-c[i-R]);
            while(tmp>M) tmp-=abs(c[i+L]-c[i-L]),L++;
            if(tmp<=M) ans=max(ans,R-L+1);
        }
    }
    rep(i,2,N){
        int L=1,R=0,tmp=0;
        while(i+R<=N&&i-1-R>=1){
            R++; tmp+=abs(c[i-1+R]-c[i-R]);
            while(tmp>M) tmp-=abs(c[i-1+L]-c[i-L]),L++;
            if(tmp<=M) ans=max(ans,R-L+1);
        }
    }
}
int main()
{
    scanf("%d",&T);
    while(T--){
        scanf("%d%s",&M,c+1); N=strlen(c+1);
        ans=0; solve();
        printf("%d\n",ans);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/hua-dong/p/9806868.html