poj 3104 Drying 二分

传送门:https://vjudge.net/problem/POJ-3104

这题是从挑战程序设计竞赛过来的。题意就是n件衣服要烘干,每件衣服都有水量,烘干机每分钟只能放进一件衣服,每分钟可以不同,每分钟能烘干的水分为k,同时每分钟没有放在洗衣机的衣服的水分会自然蒸发1,求最短需要多少时间把衣服全部烘干。

n是1e5,k是1e9,水量最大也是1e9;

二分首先要先考虑是不是有单调关系,就是越怎么样就越怎么样。这题,时间越多,就越可以烘干。所以二分时间。先对水量排个序,每次二分时间t,也就是说在没有烘干机的情况下,每件衣服可以减少t水分。那么比t小的衣服就不用烘干,比t大的就一定要烘干。计算每一件衣服要烘干的时间,也就是(a[i]-t)/(k-1),因为这一分钟选择了烘干,意味着在原来基础上减去k-1水分,然后有余数就要再多烘干一分钟。最后统计一下烘干时间是不是大于t就行了。二分复杂度是log1e9,每次遍历是O(n),可过。

这题的锅:首先要用ll,因为最坏的情况k为2,水量全都1e9。然后特判一下k=1时,不然除0会re

// Cease to struggle and you cease to live
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <set>
#include <map>
#include <stack>
using namespace std;
typedef long long ll;
ll a[100000+8];
ll n,k;
bool judge(ll t){
    int p=upper_bound(a+1,a+1+n,t)-a;
    ll tem=0;
    for(int i=p;i<=n;++i){
        ll d=a[i]-t;
        tem+=d/(k-1);
        if(d%(k-1)) ++tem;
    }
    return tem<=t;
}
int main() {
    scanf("%lld",&n);
    ll l=1,r=0,res;
    for(int i=1;i<=n;++i){
        scanf("%lld",&a[i]);
        r=max(r,a[i]);
    }
    scanf("%lld",&k);
    sort(a+1,a+1+n);
    if(k==1){
        printf("%lld",a[n]);
        return 0;
    }
    while(l<=r){
        ll m=(l+r)>>1;
        if(judge(m)){
            res=m;
            r=m-1;
        }
        else l=m+1;
    }
    printf("%lld",res);
    return 0;
}
View Code

 

posted @ 2019-05-08 23:39  小布鞋  阅读(154)  评论(0编辑  收藏  举报