HDU - 6103 :Kirinriki(不錯的尺取法)
We define the distance of two strings A and B with same length n is
dis A,B =∑ i=0 n−1 |A i −B n−1−i | 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.
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
T≤100 T≤100
0≤m≤5000 0≤m≤5000
Each character in the string is lowercase letter,
∑|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; }