HDU 6103 Kirinriki (字符串翻轉 尺取法 多校第六場)


HDU 6103 Kirinriki (字符串翻轉 尺取法)

  • 題目大意

    給定m和一個字符串,定義兩個字符串的dis兩者對應字符字典序之差,對應方式為一個從前到后,一個從后到前。然后給定一個m,先要求出最長的給定字符串的兩個子串滿足它們之間的dis小於等於m的長度。

  • 分析

    將字符串翻轉后和自己配對

    這里寫圖片描述

然后不斷錯位配對
這里寫圖片描述
注意有兩個方向的錯位配對
這里寫圖片描述

然后用尺取法取一個最長的不超過m的區間的長度即為答案

  • 代碼
#include<bits/stdc++.h>
using namespace std;
const int MAXN=5005;
int T;
int n;
int m;
char s[MAXN];
int a[MAXN];
int b[MAXN];
int c[MAXN];
int d[MAXN];
int head,tail,sum;
int max_len=0;
void Work()
{
for(int x=0;x<n;x++)//偏移
{
head=1,tail=0,sum=0;
for(int i=1;i<=n;i++)
{
if(i >= n-i-x+1)break;
d[++tail]=abs(a[i]-b[i+x]);
sum+=d[tail];
while(sum>m) sum-=d[head++];
max_len=max(max_len,tail-head+1);
}
}
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d",&m);
scanf("%s",s);
n=strlen(s);
for(int i=0;i<n;i++){a[i+1]=(int)s[i]-'a';}//從1到n
for(int i=1;i<=n;i++)b[i]=a[n-i+1];
max_len=0;
Work();
for(int i=1;i<=n;i++)c[i]=a[i];
for(int i=1;i<=n;i++)a[i]=b[i];
for(int i=1;i<=n;i++)b[i]=c[i];
Work();
printf("%d\n",max_len);
}
}
/*
2
5
abcdefedcb
5
abcdefedcb
*/


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com