比赛的时候 一直用二分然后n^2去判断,无限tle。。。。
看了别人写的代码,自己还是太蠢。。。看到求最大就一直去想二分了。tle后也一直没有换想法。。。
这题可以用尺取发法写,枚举对称轴(注意分奇偶,这点在比赛的时候想到了,然而时间复杂度不够优秀)。把对称轴两边的区间的每个对应元素的查的绝对值,存起来,然后尺取去判断,真解法真是好。
代码看了http://blog.youkuaiyun.com/f_zyj/article/details/77064212 真的很好理解。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
using namespace std;
const int MAXN = 5555;
const int MAXM = MAXN >> 1;
int n, m;
int cnt, ans;
int tmp[MAXM];
char s[MAXN];
void check()
{
int dis = 0, dis2 = 0, x1 = 0, x2 = 0;
while (x2 < cnt)
{
dis2 += tmp[x2++];
while (dis2 > m)
{
dis2 -= tmp[x1++];
}
dis = max(dis, x2 - x1);
}
ans = max(ans, dis);
}
void solve()
{
n = (int)strlen(s + 1);
ans = 0;
for (int i = 1; i <= n; i++)
{
cnt = 0;
int x1 = i - 1;
int x2 = i + 1;
while (x1 > 0 && x2 <= n)
{
tmp[cnt++] = abs(s[x1--] - s[x2++]);
}
check();
}
for (int i = 1; i <= n; i++)
{
cnt = 0;
int x1 = i;
int x2 = i + 1;
while (x1 > 0 && x2 <= n)
{
tmp[cnt++] = abs(s[x1--] - s[x2++]);
}
check();
}
}
int main()
{
int T;
scanf("%d", &T);
while (T--)
{
scanf("%d%s",&m, s + 1);
solve();
printf("%d\n", ans);
}
return 0;
}