CodeForces 650B Image Preview

直接走,或者回一次头反向走。

预处理前缀费用,反向的时候 二分查找一下。

WA点:注意一开始就可以往左。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int maxn=5e5+10;
int n;
long long a,b;
long long T;
long long sum1[maxn],sum2[maxn];
char s[maxn],e[maxn];
int ans1,ans2;

int main()
{
    scanf("%d",&n);
    scanf("%lld%lld%lld",&a,&b,&T);
    memset(s,0,sizeof s);
    scanf("%s",s);
    int len=strlen(s);
    memset(sum1,0,sizeof sum1);
    memset(sum2,0,sizeof sum2);

    ans1=0;
    if(s[0]=='w') sum1[1]=1+b;
    else sum1[1]=1;
    if(sum1[1]<=T) ans1=1;
    for(int i=1;s[i];i++)
    {
        if(s[i]=='h') sum1[i+1]=sum1[i]+a+1;
        else sum1[i+1]=sum1[i]+a+b+1;
        if(sum1[i+1]<=T) ans1=i+1;
    }

    int tot=2;

    if(s[len-1]=='w') sum2[1]=1+b;
    else sum2[1]=1;
    if(sum2[1]<=T) ans2=1;
    for(int i=len-2;i>=0;i--)
    {
        if(s[i]=='h')  sum2[tot]=sum2[tot-1]+a+1;
        else sum2[tot]=sum2[tot-1]+a+b+1;
        tot++;
    }

    for(int i=1;i<=n;i++)
    {
        long long ff=(long long)i;
        if(sum1[i]+ff*a>T) continue;
        else if(sum1[i]+ff*a<T)
        {
            int tmp=i;
            long long v=T-(sum1[i]+ff*a);

            int pos=-1;
            int l=1,r=n-i;
            int mid;
            while(l<=r)
            {
                mid=(l+r)/2;
                if(sum2[mid]<=v)
                {
                    pos=mid;
                    l=mid+1;
                }
                else r=mid-1;
            }
            if(pos!=-1) tmp=tmp+pos;
            ans1=max(ans1,tmp);
        }

    }

    memset(e,0,sizeof e);
    e[0]=s[0]; int y=1;
    for(int i=len-1;i>=1;i--) e[y++]=s[i];

    strcpy(s,e);

    memset(sum1,0,sizeof sum1);
    memset(sum2,0,sizeof sum2);

    ans2=0;
    if(s[0]=='w') sum1[1]=1+b;
    else sum1[1]=1;
    for(int i=1;s[i];i++)
    {
        if(s[i]=='h') sum1[i+1]=sum1[i]+a+1;
        else sum1[i+1]=sum1[i]+a+b+1;
        if(sum1[i+1]<=T) ans2=i+1;
    }

    tot=2;

    if(s[len-1]=='w') sum2[1]=1+b;
    else sum2[1]=1;

    for(int i=len-2;i>=0;i--)
    {
        if(s[i]=='h')  sum2[tot]=sum2[tot-1]+a+1;
        else sum2[tot]=sum2[tot-1]+a+b+1;
        tot++;
    }

    for(int i=1;i<=n;i++)
    {
        long long ff=(long long)i;
        if(sum1[i]+ff*a>T) continue;
        else if(sum1[i]+ff*a<T)
        {
            int tmp=i;
            long long v=T-(sum1[i]+ff*a);

            int pos=-1;
            int l=1,r=n-i;
            int mid;
            while(l<=r)
            {
                mid=(l+r)/2;
                if(sum2[mid]<=v)
                {
                    pos=mid;
                    l=mid+1;
                }
                else r=mid-1;
            }
            if(pos!=-1) tmp=tmp+pos;
            ans2=max(ans2,tmp);
        }

    }

    printf("%d\n",max(ans1,ans2));
    return 0;
}

 

posted @ 2016-03-08 08:40  Fighting_Heart  阅读(299)  评论(0编辑  收藏  举报