1. 程式人生 > >【POJ - 3104 】Drying(二分)

【POJ - 3104 】Drying(二分)

Drying

直接上中文

Descriptions

每件衣服都有一定單位水分,在不使用烘乾器的情況下,每件衣服每分鐘自然流失1個單位水分,但如果使用了烘乾機則每分鐘流失K個單位水分,但是遺憾是隻有1臺烘乾機,每臺烘乾機同時只能烘乾1件衣服,請問要想烘乾N件衣服最少需要多長時間?

輸入

多組輸入

第一行輸入N,表示有N件衣服,第二行輸入N件衣服的水分ai,第三行表示烘乾機每分鐘烘乾水分K 
其中
1 ≤ N ≤ 100 000,1 ≤ ai ≤ 10^9,1 ≤ K≤ 10^9輸出

輸出

烘乾N件衣服所需要的最短時間

樣例輸入

3
2 3 9
5
3 2 3 6 5

樣例輸出

3
2

題目連結

https://vjudge.net/problem/POJ-3104

 

二分的時間在算的時候首先減去這個時間作為自然風乾,然後用烘乾機的話每分鐘就只能掉k-1的水(因為烘乾的時候是不會自然風乾的,然後需要特殊處理k=1的情況)

注意要用scanf printf 不然會超時

 

AC程式碼

#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#define Mod 1000000007
#define eps 1e-6
#define ll long long
#define INF 0x3f3f3f3f
#define MEM(x,y) memset(x,y,sizeof(x))
#define Maxn 100000+100
using namespace std;
int N,K;
ll l,r,mid;//左右中
ll a[Maxn];
ll ans;
int solve()
{
    mid=(l+r)/2;//預判時間
    ll cnt=0;//實際時間
    for(ll i=0; i<N; i++)
    {
        if(a[i]<=mid)//小於預判時間,即可以在規定時間內自然風乾
            continue;
        else//需要藉助烘乾機
            cnt+=(a[i]-mid+K-2)/(K-1);//所需時間
        if(cnt>mid)//實際時間大於預判時間,失敗
            return 0;
    }
    return 1;
}
int main()
{
    while(scanf("%d",&N)!=EOF)
    {
        l=0;//初始化
        r=0;
        for(ll i=0; i<N; i++)
        {
            scanf("%lld",&a[i]);
            r=max(r,a[i]);
        }
        scanf("%d",&K);
        if(K==1)//K==1,特殊處理
            cout<<r<<endl;
        else
        {
            ans=INF;//答案最小時間
            while(l<=r)
            {
                if(!solve())//失敗,即預判時間小了,需要增大預判時間
                    l=mid+1;
                else//成功,減少預判時間,看是否有跟小的答案
                {
                    ans=min(mid,ans);
                    r=mid-1;
                }
            }
            printf("%lld\n",ans);
        }
    }
    return 0;
}

&n