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

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]存的是兩子串的距離
                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);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章