hdu 6103 Kirinriki 尺取
2017-08-11 19:33
218 查看
传送门
转自:这里
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=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
14622
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 double
typedef 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);
}
}
相关文章推荐
- 2017 Multi-University Training Contest - Team 6 HDU 6103 Kirinriki (尺取法)
- Hdu 6103 Kirinriki【区间DP+二分】
- hdu 6103 Kirinriki 尺取
- HDU 6103 Kirinriki(尺取法)
- hdu 6103 Kirinriki 尺取
- Kirinriki HDU - 6103
- HDU 6103 Kirinriki(尺取法)
- HDU 2017 多校联合训练赛6 1008 6103 Kirinriki 优美的暴力
- hdu 6103(Kirinriki)
- hdu 6103 Kirinriki 尺取
- HDU 6103 Kirinriki
- hdu 6103 Kirinriki(多校联赛)
- hdu 6103 Kirinriki 尺取
- 2017多校六 1008题 hdu 6103 Kirinriki 尺取法
- HDU 6103 Kirinriki(尺取)
- HDU 6103 Kirinriki (思维 双指针)
- hdu 6103 Kirinriki 尺取
- HDU-6103 Kirinriki - 2017 Multi-University Training Contest - Team 6(尺取)
- HDU 6103 Kirinriki【尺取法】【思维题】【好题】
- hdu 6103 Kirinriki(尺取法)