Codeforces Round #345 (Div. 2) D 细节题

  这个题的意思是给你n张首尾相接的照片, 当前照片在1, 每次只能转移一个单位, 转移时间为a, 照片有可能颠倒, 将照片摆正需要的时间为b, 看照片的时间为1, 想要看尽可能多的照片, 问这个数量是多少, 我们可以预处理查看每张照片需要的时间, 然后枚举从左边看需要的时间, 从右边看需要的时间, 二分从另外一边看需要的时间即可, 代码如下:

#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;
int n, a, b, T;
char s[500000+10];
long long d[500000+10], d1[500000+10];

int main()
{
    scanf("%d%d%d%d", &n, &a, &b, &T);
    scanf("%s", s+1);
    for(int i=1; i<=n; i++)
        if(s[i] == 'w') d[i] = d[i-1] + b + 1;
        else d[i] = d[i-1] + 1;
    for(int i=n; i>=1; i--)
        if(s[i] == 'w') d1[i] = d1[i+1] + b + 1;
        else d1[i] = d1[i+1] + 1;
    int res = 0;
    for(int i=1; i<=n; i++)
    {
        // 1 -> i
        int t1 = T - d[i] - (i-1)*a;
        if(t1 < 0) break;
        res = max(res, i);
        t1 -= (i-1)*a;
        if(t1<0) continue;
        int l=i+1, r=n;
        int tpr = r+1;
        while(l <= r)
        {
            int mid = (l+r)/2;
            if(t1-((n-mid+1)*a+d1[mid]) < 0) l = mid + 1;
            else
            {
                r = mid - 1;
                tpr = mid;
            }
        }
        res = max(res, i+n-tpr+1);
    }

    for(int i=n; i>=2; i--)
    {
        int t1 = T - (n-i+1)*a - d1[i] - d[1];
        if(t1 < 0) break;
        res = max(res, n-i+2);
        t1 -= (n-i+1)*a;
        if(t1 < 0) continue;

        int l=2, r=i-1;
        int tpr = 1;
        while(l <= r)
        {
            int mid = (l+r)/2;
            if(t1-((mid-1)*a+d[mid]-d[1]) < 0) r = mid - 1;
            else
            {
                tpr = mid;
                l = mid + 1;
            }
        }
        res = max(res, tpr+n-i+1);
    }
    printf("%d\n", res);
    return 0;
}

 

posted @ 2016-03-09 11:51  xing-xing  阅读(221)  评论(0编辑  收藏  举报