原题链接:
HDU-6103
大意:
给一个串,求两个不重叠的长度均为
n
的子串
disA,B=∑i=0n−1|Ai−Bn−1−i|
思路:
题目和样例都给了暗示,回文串。
可以发现两个子串一定存在一个对称中心,围绕对称中心往外做,双指针维护即可。找到大于
m
<script type="math/tex" id="MathJax-Element-561">m</script> 的就进行维护。
做的时候两条 for 语句写起来比较清晰,对称中心在空隙处一个,对称中心为数字一个。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define mem(s,t) memset(s,t,sizeof(s))
#define D(v) cout<<#v<<" "<<v<<endl
#define inf 0x3f3f3f3f
//#define LOCAL
inline void read(int &x){
x=0;char p=getchar();
while(!(p<='9'&&p>='0'))p=getchar();
while(p<='9'&&p>='0')x*=10,x+=p-48,p=getchar();
}
const int MAXN=5000+10;
char s[MAXN];
int m;
int main() {
#ifdef LOCAL
freopen("1008.in","r",stdin);
freopen("out.txt","w",stdout);
#endif
int t;
read(t);
while(t--){
mem(s,0);
read(m);
scanf("%s",s);
int len=strlen(s);
int ans=0;
int n=0;
for(int i=1;i<len;i++){//对称中心为数字之间空隙
for(int l=i-1,r=i+1,pr=r,pl=l,ret=0;r<len && l>=0;r++,l--){
ret+=abs(s[r]-s[l]);
while(ret>m && pr<=r){
ret-=abs(s[pr++]-s[pl--]);
}
n=max(n,r-pr+1);
}
}
for(int i=1;i<len;i++){//对称中心为数字
for(int l=i-1,r=i,pr=r,pl=l,ret=0;r<len && l>=0;r++,l--){
ret+=abs(s[r]-s[l]);
while(ret>m && pr<=r){
ret-=abs(s[pr++]-s[pl--]);
}
n=max(n,r-pr+1);
}
}
printf("%d\n",n);
}
return 0;
}