Drying POJ - 3104

題目描述:晾衣服,洗衣機一分鐘可以晾K水,自然風乾一分鐘可以減少1水。求晾乾所有衣服所需要的最小時間。
解題思路:二分時間,那怎麼計算滿足的時間呢。轉換一下思路,總時間就是洗衣機工作的時間,因爲如果只有自然風乾的話,時間是<=洗衣機總是工作的,什麼時候=呢,是k=1的時候。那麼下面計算洗衣機工作的時間,列一個方程組,求每件衣服需要洗衣機洗的時間t2。t1*1+t2*k>=w[i],t1+t2=mid(每次二分的總時間),t1是自然風乾的時間。得出t2>=(w[i]-mid)/(k-1),如果(w[i]-mid)%(k-1)!=0,那麼t2就得+1.另外還需要注意的地方時分母k-1不能等於0,所以需要特殊處理。

代碼如下:

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;

const int maxn=100000+10;
int w[maxn],n,k;

bool judge(int mid)
{
    int tol=0;
    for(int i=0;i<n;i++)
    {
        if(w[i]-mid>0)
        {
            if(k==1) tol+=(w[i]-tol);
            else
            {
               if((w[i]-mid)%(k-1))  tol+=(w[i]-mid)/(k-1)+1;
               else tol+=(w[i]-mid)/(k-1);
            }
        }
        if(tol>mid) return false;
    }
   return true;
}

int main()
{
    scanf("%d",&n);
    int mmax=-1;
    for(int i=0;i<n;i++)
    {
        scanf("%d",w+i);
        mmax=max(mmax,w[i]);
    }
    scanf("%d",&k);
    sort(w,w+n,greater<int>());
    int l=0,r=mmax*2,ans=l+(r-l)/2;
    while(r-l>1)
    {
        int mid=l+(r-l)/2;
        if(judge(mid))
        {
            ans=mid;
            r=mid;
        }
        else l=mid;
    }
    cout << ans << endl;
    return 0;
}

另外二分的時候控制條件和邊界處理,還有輸出哪一個變量都是些小細節,需要考慮。比如控制條件是r-l>1,那麼只需要如上代碼那樣就行,輸出可以是最後的mid或r。如果控制條件是r>=l,則需要寫成r=mid-1,l=mid+1,這樣才能保證跳出循環,最後可以輸出最後的mid或者l。如果控制條件是r>l,則得寫成l=mid+1,r=mid,這樣才能保證跳出循環,最後可以輸出最後的mid或l。最後總結r和l爲什麼要這樣寫的,因爲要保證能跳出循環,使得l可以大於r,如果只是讓r=mid,l=mid,則二分到最後,r-l=1,永遠跳不出循環,所以循環控制條件寫成r-l>1也是可行的。
之前做浮點數的二分題,二分到最後,l,r,mid相差極其微小,所以是在誤差範圍之內的,最後輸出lr,mid都行,但做整型數的時候,二分到最後l,r相差1,具體輸出哪一個就不一樣了,但是無論是浮點數還是整型數,最後輸出mid應該不會錯。

發佈了46 篇原創文章 · 獲贊 6 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章