codeforces #262 DIV2 C称号Present(二分法+贪婪)

职务地址:http://codeforces.com/contest/460/problem/C

这个题是用二分枚举最小值。然后推断是否能在规定的次数内使得全部的数都达到这个值。推断的时候要用贪心的方法推断,从左往右遍历。这时候须要让每次浇花的范围尽量向右。所以当到达一个不得不浇花的地方时,要继续占用所须要的浇花次数。当浇花次数不够用的时候,就说明无法达到。

在我的代码中,c数组是记录当前到了该点的时候浇花范围的最右界。表示到了这个地方的时候少了多少次覆盖。y就代表当前这个数被多少个浇花范围覆盖。x是指还剩余的浇花次数。

忘了初始化。。二分非常明显不好调试。

。调了将近20分钟才发现忘了对C数组初始化。。

。sad。

。。。

代码例如以下:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <algorithm>
#include <queue>
using namespace std;
#define LL __int64
LL a[110000], b[110000], c[110000];
int main()
{
    LL n, m, i, w, ans, x, y;
    scanf("%I64d%I64d%I64d",&n,&m,&w);
    for(i=0;i<n;i++)
    {
        scanf("%I64d",&a[i]);
    }
    memset(c,0,sizeof(c));
    LL low=1, high=1e10, mid;
    while(low<=high)
    {
        mid=(high+low)/2;
        //printf("%I64d
",mid);
        x=m;
        y=0;
        memset(c,0,sizeof(c));
        int flag=0;
        for(i=0;i<n;i++)
        {
            b[i]=mid-a[i];
            if(b[i]<0)
                b[i]=0;
        }
        for(i=0;i<n;i++)
        {
            y+=c[i];
            b[i]-=y;
            if(b[i]>0)
            {
                if(x-b[i]<0)
                {
                    flag=1;
                    break;
                }
                else
                {
                    x-=b[i];
                    y+=b[i];
                    if(i+w<n)
                    c[i+w]-=b[i];
                }
            }
        }
        //printf("%I64d   %d
",mid, flag);
        if(flag)
        {
            high=mid-1;
        }
        else
        {
            ans=mid;
            low=mid+1;
        }
        //printf("%I64d
",ans);
    }
    printf("%I64d
",ans);
    return 0;
}


版权声明:本文博客原创文章。博客,未经同意,不得转载。

原文地址:https://www.cnblogs.com/mengfanrong/p/4660488.html