2017第六次多校联合hdu6103

来源:互联网 发布:淘宝客服旺旺怎么联系 编辑:程序博客网 时间:2024/06/05 17:09

题目

题意还是比较好理解的,就是求小于所给m的最大dis的子串最大长度。

题解:首先正方向枚举每一个点,固定这个点作为开始的左边界。然后分别从这个左边界和最后一个点开始拿,直到dis>m,这时候更新长度最大值,然后把已经前面已经拿的点减去,直到dis<m,这样再开始拿。对于每个左边界都进行这样的操作。然后方向再来一次就好了。

#include<bits/stdc++.h>using namespace std;const int maxn=5000+100;char s[maxn],a[maxn];int main(){    int t;    //freopen("data.in","r",stdin);    scanf("%d",&t);    while(t--)    {        int n;        scanf("%d",&n);        memset(s,0,sizeof s);        memset(a,0,sizeof a);        scanf("%s",s);        int l=strlen(s);        int mount=0;        for(int i=l-1;i>=0;i--)        {            a[i]=s[mount++];        }        int ans=-1,dis=0;        for(int i=0;i<l;i++)        {            int r=l-1,dis=0;            int pl=i,pr=r,sum=0;            for(int j=i;j<r;j++,r--)            {                dis+=abs(a[j]-a[r]);                sum++;                while(j<r&&dis>n)                {                    dis-=abs(a[pl++]-a[pr--]);                    sum--;                }                ans=max(ans,sum);            }            ans=max(ans,sum);        }        for(int i=0;i<l;i++)        {            int r=l-1,dis=0;int pl=i,pr=r,sum=0;            for(int j=i;j<r;j++,r--)            {                dis+=abs(s[j]-s[r]);                sum++;                while(j<r&&dis>n)                {                    dis-=abs(s[pl++]-s[pr--]);                    sum--;                }                ans=max(ans,sum);            }            ans=max(ans,sum);        }        printf("%d\n",ans);    }}
原创粉丝点击