枚举 +尺取
题意:
给出一个字符串,问两个不相交的字串对称相减的绝对值和小于等于 m的最长长度。
思路:
如果存在两个不相交的字串,那么必然两个字串之间存在对称轴,分为两种:
1. 子串之间有奇数个其它字符,那么枚举其中的字符。
2. 子串之间有偶数个其它字符,那么枚举其中的空格。
对称轴确定之后,对对称的串计算出其对称相减的和保存在数组中,那么问题转化为,在一个数组中找出和小雨等于m的最长连续字串,尺取法的经典应用。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int maxn = 5005;
int m,ans,pos;
int a[maxn];
char s[maxn];
int Find(int n)
{
int sum = 0,ans = 0,cnt = 0,t = 0;
while(1) {
while(cnt < n && sum + a[cnt] <= m) {
sum += a[cnt++];
ans = max(ans,cnt - t);
}
sum -= a[t++];
if(t >= n) break;
}
return ans;
}
int main(int argc, char const *argv[])
{
// freopen("in.txt","r",stdin);
int tt;
scanf("%d",&tt);
while(tt--) {
scanf("%d",&m);
scanf("%s",s+1);
int len = strlen(s+1);
ans = 0;
for(int i = 1;i <= len; i++) {
int pos = 0;
for(int j = 1;j+i <= len && i-j > 0; j++) {
a[pos++] = abs(s[j+i] - s[i-j]);
}
ans = max(ans,Find(pos));
}
for(int i = 1;i <= len-1; i++) {
pos = 0;
for(int j = 0;j+i+1 <= len && i-j > 0; j++) {
a[pos++] = abs(s[j+i+1] - s[i-j]);
}
ans = max(ans,Find(pos));
}
printf("%d\n",ans);
}
return 0;
}
永不言弃!!!