hdu 6103 Kirinriki(尺取法)

来源:互联网 发布:金十数据. 编辑:程序博客网 时间:2024/05/16 11:30

Kirinriki

题目链接:Kirinriki

题意:找两个不重叠的子串A,B。 使得disAB<=m

dis(A,B)=n1i=0|AiBn1i|。求最长的字符串长度。

思路:
直接枚举终点,由于奇偶位的不同,所以我们需要枚举奇和偶两种情况

官方题解:

这里写图片描述

代码:

#include<bits/stdc++.h>using namespace std;const int maxn=5e3+5;char str[maxn];int m,ans,len;void solve(int ed1,int ed2){    int st1=ed1,st2=ed2,tot=0;    if(ed1<0)        return ;    while(st1>=0&&st2<len)    {        if(tot+abs(str[st1]-str[st2])<=m)        {            tot+=abs(str[st1]-str[st2]);            ans=max(ans,ed1-st1+1);            --st1,++st2;        }        else        {            tot-=abs(str[ed1]-str[ed2]);            --ed1,++ed2;        }    }}int main(){    int T_T;    scanf("%d",&T_T);    while(T_T--)    {        scanf("%d %s",&m,str);        len=strlen(str);        ans=0;        for(int i=0;i<len-1;++i)        {            solve(i,i+1);            solve(i-1,i+1);        }        printf("%d\n",ans);    }    return 0;}



ps:我在比赛过程中写的是枚举起点,分为
st1=0,st2=[1,len-1]
st1=len-1,st2=[0,len-2]两种情况

当时吧,认为这样写肯定是对的,于是想都没想清楚就交了,结果wrong了无数发。。。(思路真的是对的,是我的过程有一点错误-_-)

AC代码:

#include<bits/stdc++.h>using namespace std;const int maxn=5e3+5;char str[maxn];int m;int main(){    int t;    scanf("%d",&t);    while(t--)    {        scanf("%d",&m);        scanf("%s",str);        int len=strlen(str),ans=0;        for(int l=1;l<len;++l)        {            int st1=0,st2=st1+l;            int tot=abs(str[st1]-str[st2]);            while(tot>m)            {                ++st1,--st2;//这里写成了++st1,++st2 ︸_︸                if(st1>=st2)                    break;                tot=abs(str[st1]-str[st2]);            }            if(st1>=st2)                continue;            int ed1=st1,ed2=st2;            while(1)            {                while(tot<=m)                {                    ans=max(ans,ed1-st1+1);                    ++ed1,--ed2;                    if(ed1>=ed2)                        break;                    tot+=abs(str[ed1]-str[ed2]);                }                if(ed1>=ed2)                    break;                while(tot>m)                {                    tot-=abs(str[st1]-str[st2]);                    ++st1,--st2;                    if(st1>ed1||st2<ed2)                        break;                }                if(st1>ed1||st2<ed2)                    break;            }        }        for(int l=1;l<len;++l)        {            int st1=len-1,st2=st1-l;            int tot=abs(str[st1]-str[st2]);            while(tot>m)            {                --st1,++st2;//这里写成了--st1,--st2 T_T                if(st1<=st2)                    break;                tot=abs(str[st1]-str[st2]);            }            if(st1<=st2)                continue;            int ed1=st1,ed2=st2;            while(1)            {                while(tot<=m)                {                    ans=max(ans,ed2-st2+1);                    --ed1,++ed2;                    if(ed2>=ed1)                        break;                    tot+=abs(str[ed1]-str[ed2]);                }                if(ed2>=ed1)                    break;                while(tot>m)                {                    tot-=abs(str[st1]-str[st2]);                    --st1,++st2;                    if(st1<ed1||st2>ed2)                        break;                }                if(st1<ed1||st2>ed2)                    break;            }        }        printf("%d\n",ans);    }    return 0;}
原创粉丝点击