hdu 6103 (尺取法)

来源:互联网 发布:无限网络万能钥匙 编辑:程序博客网 时间:2024/04/30 05:43

We define the distance of two strings A and B with same length n is 
disA,B=i=0n1|AiBn1i|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 
T100T≤100 
0m50000≤m≤5000 
Each character in the string is lowercase letter, 2|S|50002≤|S|≤5000 
|S|20000∑|S|≤20000 
Output
For each test case output one interge denotes the answer : the maximum length of the substring. 
Sample Input
15abcdefedcb
Sample Output
5          
Hint
[0, 4] abcde[5, 9] fedcbThe distance between them is abs('a' - 'b') + abs('b' - 'c') + abs('c' - 'd') + abs('d' - 'e') + abs('e' - 'f') = 5
很巧妙地尺取。。。从前面枚举总的长度,然后尺取当前长度所能产生的最长的可行串,具体方法是取中点,然后延伸可行长度,更新最大值,不可行的时候删除最前端的影响,其实就是固定了起点和终点进行暴力枚举
一开始想的是用尺取法移串可是这样复杂度太高了 重复算太多了,也不好操作
这里固定了起点和终点然后每次枚举就变成on了
#include <bits/stdc++.h>using namespace std;const int maxn = 5010;char s[maxn];int ans=0;int len,m;void solve(){    for(int i=2;i<=len;i++)    {        int h=i/2;        int sum=0;        int l=0;        for(int j=0;j<h;j++)        {            sum+=abs(s[j]-s[i-j-1]);            while(sum>m&&l<j)             {                sum-=abs(s[l]-s[i-l-1]);                l++;            }            if(sum<=m)            ans=max(ans,j-l+1);        }    }}int main(){    int t;    scanf("%d",&t);    while(t--)    {        scanf("%d",&m);        scanf("%s",s);        len = strlen(s);        ans=0;        solve(),        reverse(s,s+len); solve();        printf("%d\n",ans );    }    return 0;}



原创粉丝点击