hdu6103Kirinriki(第六場尺取法取區間最大)

Kirinriki

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1822    Accepted Submission(s): 749


Problem Description
We define the distance of two strings A and B with same length n is
disA,B=i=0n1|AiBn1i|
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
T100
0m5000
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
 

Source

求最大字串,使得交叉相減絕對值和最大且不超過m的字串長度
處理區間最大問題用尺取法,從a開始枚舉,如果枚舉的res值超過m,則退回到開頭,下次該區間跳過枚舉,枚舉到最後一個字符時,枚舉起始地址+1。
下面舉例說明:
1
2
abcd
####0-1=1
####0-2=3
****0-2=1
l ---->0
^^^^0-2=-1
####0-2=1
####0-3=4
****0-3=1
l ---->0
^^^^0-3=-2
####0-3=1
####1-2=2
2

帶#號的爲第一次枚舉,*號爲超出了m,去掉當前枚舉值,^爲繼續後退,得到新的起始值,繼續枚舉
最後直到枚舉到1-2結束,輸出ans=2

#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;

const int maxn=20005;
char s[maxn];
int m,len;

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&m);
        scanf("%s",s);
        len=strlen(s);
        int ans=0;
        for(int i=0;i<len;i++)
        {
            int t=0,res=0,l=0;
            for(int j=0;j<(i+1)/2;j++)
            {
                res+=abs(s[j]-s[i-j]);
                //printf("####%d-%d=%d\n",j,i-j,ans);
                if(res<=m)
                {
                    t++;
                    ans=max(t,ans);
                }
                else
                {
                    res-=abs(s[j]-s[i-j]);
                    //printf("****%d-%d=%d\n",j,i-j,ans);
                    res-=abs(s[l]-s[i-l]);
                    //printf("l ---->%d\n",l);
                    //printf("^^^^%d-%d=%d\n",j,i-j,ans);
                    l++,t--,j--;
                }
            }
        }
        reverse(s,s+len);
        //cout<<s<<endl;
        for(int i=0;i<len;i++)
        {
            int t=0,res=0,l=0;
            for(int j=0;j<(i+1)/2;j++)
            {
                res+=abs(s[j]-s[i-j]);
                if(res<=m)
                {
                    t++;
                    ans=max(t,ans);
                }
                else
                {
                    res-=abs(s[j]-s[i-j]);
                    res-=abs(s[l]-s[i-l]);
                    l++,t--,j--;
                }
            }
        }
        printf("%d\n",ans);
    }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章