噩梦多校6。。HDU6103 Kirinriki(字符串,尺取法)

2 篇文章 0 订阅
2 篇文章 0 订阅

噩梦多校6,HDU6103 Kirinriki

Problem Description
We define the distance of two strings A and B with same length n is
disA,B= k1 |Ai−Bn−1−i| (k=n-1)
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 them is abs(‘a’ - ‘b’) + abs(‘b’ - ‘c’) + abs(‘c’ - ‘d’) + abs(‘d’ - ‘e’) + abs(‘e’ - ‘f’) = 5

题意:给一个字符串,设A,B是他的子串,AB长度相等且AB没有重叠,求满足disA,B<=m的最小长度。


这题其实不难,比赛的时候已经想到枚举对称中心了,可是没想到用尺取法来取,还是练的少,脑子不好。AB对称中心有两种,一种是以一个字符对称,另一种是以一个空位对称


下面是我看过题解后的ac代码

#include<iostream>
#include<cstdio>
#include<string.h>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;
int n,m,T,ans;
string s;
int k;
int getans()
{
    int len=s.length();
    int sum,ans=0;
    for(int i=0;i<len;i++)  //对称中心是字符
    {    sum=0;
        for(int l=i,r=i,pl=l,pr=r;l>=0&&r<len;l--,r++)
        {
            sum+=abs(s[r]-s[l]);
            while(sum>m&&pr<=r) sum-=abs(s[pr++]-s[pl--]);
            ans=max(ans,r-pr+(pr!=i));
        }
    }
    for(int i=1;i<len;i++)  //对称中心是空位
    {
        sum=0;
        for(int l=i-1,r=i,pl=l,pr=r;l>=0&&r<len;l--,r++)
        {
            sum+=abs(s[r]-s[l]);
            while(sum>m&&pr<=r) sum-=abs(s[pr++]-s[pl--]);
            ans=max(ans,r-pr+1);
        }
    }return ans;
}
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&m);
        cin>>s;
        printf("%d\n",getans());
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值