hdu 6103 Kirinriki 尺取

来源:互联网 发布:c语言初级程序 编辑:程序博客网 时间:2024/04/30 06:38

传送门

转自:这里

Kirinriki

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


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
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
 

Source
2017 Multi-University Training Contest - Team 6
 

Recommend
liuyiding   |   We have carefully selected several similar problems for you:  6107 6106 6105 6104 6103 

题目描述

给定一个字符串,问最大字串长度为多少的时候交叉相减的绝对值之和小于等于输入的m,注意,子串不能重合。

解题思路

最原来以为要一个一个的循环遍历,这样的话时间复杂度太大,中间也有很多的重复的部分,考虑到这些因素的话,用尺取法来考虑这个问题。

首先我们可以假设 A 一定在 B 左边,然后我们可以考虑A的起点和B的尾部,如果暂时不考虑长度不固定,我们每次查找都让长度尽可能长,那么,我们一定需要将 A的起点和B的尾部,然后获取 A 向右延伸,B 向左延伸对应位置的贡献,然后呢?我们可以采用尺取法来进行A的起点和B的尾部向中间的推移,当 此时的dis值大于 m 时,我们向中间推移 A的起点和B的尾部即可。在这个尺取法的过程中,记录下来最大的 dis 值即可。

简单的说就是,将整个区间划分为两份,然后左右各有一个序列,这个序列是贪心的,贪心的过程利用尺取法来维护最优解,而这里我们需要对区间的划分进行枚举。

这样的话考虑到一种情况就是每次的时候,我们都是在用这个字符串的后半部分来匹配前半部分的任意一种情况,相当于后半部分的字符串是基本上固定的,这样的话匹配的可能行机会减少,为了解决设个问题,我们只需要将字符串逆序,再按照你这的字符串同样的方法比较一下,找出其中的最大值即可。

//china no.1#pragma comment(linker, "/STACK:1024000000,1024000000")#include <vector>#include <iostream>#include <string>#include <map>#include <stack>#include <cstring>#include <queue>#include <list>#include <stdio.h>#include <set>#include <algorithm>#include <cstdlib>#include <cmath>#include <iomanip>#include <cctype>#include <sstream>#include <functional>#include <stdlib.h>#include <time.h>#include <bitset>using namespace std;#define pi acos(-1)#define endl '\n'#define srand() srand(time(0));#define me(x,y) memset(x,y,sizeof(x));#define foreach(it,a) for(__typeof((a).begin()) it=(a).begin();it!=(a).end();it++)#define close() ios::sync_with_stdio(0); cin.tie(0);#define FOR(x,n,i) for(int i=x;i<=n;i++)#define FOr(x,n,i) for(int i=x;i<n;i++)#define W while#define sgn(x) ((x) < 0 ? -1 : (x) > 0)#define bug printf("***********\n");#define db doubletypedef long long LL;const int INF=0x3f3f3f3f;const LL LINF=0x3f3f3f3f3f3f3f3fLL;const int dx[]={-1,0,1,0,1,-1,-1,1};const int dy[]={0,1,0,-1,-1,1,-1,1};const int maxn=2e4+10;const int maxx=1e6+100;const double EPS=1e-7;const int mod=10000007;template<class T>inline T min(T a,T b,T c) { return min(min(a,b),c);}template<class T>inline T max(T a,T b,T c) { return max(max(a,b),c);}template<class T>inline T min(T a,T b,T c,T d) { return min(min(a,b),min(c,d));}template<class T>inline T max(T a,T b,T c,T d) { return max(max(a,b),max(c,d));}template <class T>inline bool scan_d(T &ret){char c;int sgn;if (c = getchar(), c == EOF){return 0;}while (c != '-' && (c < '0' || c > '9')){c = getchar();}sgn = (c == '-') ? -1 : 1;ret = (c == '-') ? 0 : (c - '0');while (c = getchar(), c >= '0' && c <= '9'){ret = ret * 10 + (c - '0');}ret *= sgn;return 1;}inline bool scan_lf(double &num){char in;double Dec=0.1;bool IsN=false,IsD=false;in=getchar();if(in==EOF) return false;while(in!='-'&&in!='.'&&(in<'0'||in>'9'))in=getchar();if(in=='-'){IsN=true;num=0;}else if(in=='.'){IsD=true;num=0;}else num=in-'0';if(!IsD){while(in=getchar(),in>='0'&&in<='9'){num*=10;num+=in-'0';}}if(in!='.'){if(IsN) num=-num;return true;}else{while(in=getchar(),in>='0'&&in<='9'){num+=Dec*(in-'0');Dec*=0.1;}}if(IsN) num=-num;return true;}void Out(LL a){if(a < 0) { putchar('-'); a = -a; }if(a >= 10) Out(a / 10);putchar(a % 10 + '0');}void print(LL a){ Out(a),puts("");}//freopen( "in.txt" , "r" , stdin );//freopen( "data.txt" , "w" , stdout );//cerr << "run time is " << clock() << endl;char s[maxn];int m;int solve(){    int ans=0,len=strlen(s+1);    for(int i=len;i>=1;i--)    {        int p=0,d=0,t=0,cnt=i/2-1;        for(int j=0;j<=cnt;j++)        {            d+=abs(s[1+j]-s[i-j]);            //cout<<1+j<<" "<<i-j<<" "<<p<<endl;            if(d>m)            {                d-=abs(s[1+p]-s[i-p]);                d-=abs(s[1+j]-s[i-j]);                p++;                t--;                j--;            }            else            {                t++;                ans=max(ans,t);            }        }    }    return ans;}int main(){    int t;    //freopen( "in.txt" , "r" , stdin );    //freopen( "1.txt" , "w" , stdout );    scan_d(t);    W(t--)    {        scan_d(m);        scanf("%s",s+1);        int ans=solve(),len=strlen(s+1);        reverse(s+1,s+len+1);        ans=max(ans,solve());        print(ans);    }}