HDU 6103 Kirinriki(尺取法)

来源:互联网 发布:java字符串数组 \0 编辑:程序博客网 时间:2024/05/17 02:11

先暴力,因为这题大致就相当于取最长“对称串”,这个“对称串”只要满足题目的d

#include<bits/stdc++.h>using namespace std;int t,m;int dp[10100];char str[10050];int main(){    scanf("%d",&t);    while(t--)    {        scanf("%d",&m);        scanf("%s",str);        int len = strlen(str);        int ans=0;        int laz=0;        for(int i=0;i<2*len-1;i++)//表示对称点,因为对称部分可以在两个字符之间的留白部分,所以循环两倍len,一定不要像manacher那样子加字符找,时间多四倍肯定不够。会TLE。        {            int sum=0;int num=0;            memset(dp,0,sizeof(dp));            if(i%2)            {                int ibegin=i/2;                int iend = i/2+1;                while(ibegin>=0&&iend<len)                {                    dp[i/2-ibegin+1] = abs((int)(str[ibegin]-str[iend]));                    ibegin--;iend++;                }                int t=1;int s=1;                for(;;)//尺取                {                    while(t<=i/2-ibegin&&sum<=m)                    {                        sum+=dp[t++];                    }                    if(sum>m)                        ans=max(t-s-1,ans);                    else ans=max(ans,t-s);                    if(sum<m) break;                    sum-=dp[s++];                }            }            else            {                int ibegin=i/2-1;                int iend = i/2+1;                while(ibegin>=0&&iend<len)                {                    dp[i/2-ibegin] = abs((int)(str[ibegin]-str[iend]));                    ibegin--;iend++;                }                int t=1;int s=1;                for(;;)                {                    while(t<=i/2-1-ibegin&&sum<=m)                    {                        sum+=dp[t++];                    }                    if(sum>m)                        ans=max(t-s-1,ans);                    else ans=max(ans,t-s);                    if(sum<m) break;                    sum-=dp[s++];                }            }        }        printf("%d\n",ans);    }}
原创粉丝点击