1. 程式人生 > >codeforces #262 DIV2 C題Present(二分+貪心)

codeforces #262 DIV2 C題Present(二分+貪心)

這個題是用二分列舉最小值,然後判斷能否在規定的次數內使得所有的數都達到這個值。判斷的時候要用貪心的方法判斷,從左往右遍歷,這時候需要讓每次澆花的範圍儘量向右。所以當到達一個不得不澆花的地方時,要繼續佔用所需要的澆花次數。當澆花次數不夠用的時候,就說明無法達到。

在我的程式碼中,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\n",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\n",mid, flag);
        if(flag)
        {
            high=mid-1;
        }
        else
        {
            ans=mid;
            low=mid+1;
        }
        //printf("%I64d\n",ans);
    }
    printf("%I64d\n",ans);
    return 0;
}