poj3104

大体思路:
题意:烘干机,给出一堆衣服的水分a[i],在不加烘干机情况下自动每一分钟减少1水分,每分钟可以变改衣服(i)到烘干机中,每分钟减少k水分,求最少需要多少时间。
题解:第一时间就想到使用二分枚据答案+验证这种思路,不过这题还是有些陷阱需要注意。
1. 验证答案时,如果 a[i] <= mid,让它自然烘干即可 ; 如果a[i] > mid,那么烘干这件衣服可以分成两段时间:使用烘干机时间x1 + 自然烘干时间x2,那么可以列出等式:mid = x1 + x2; a[i] <= kx1+x2;于是得x1 >= (a[i] -mid)/(k-1);即得使用烘干机的最少时间x1
2.注意当k==1时,k-1 == 0,需要特殊处理,直接打出ans = maxV
3.注意当求left+right时,结果可能超出范围,正确的方法应该是left + (right - left)*0.5;
4.一个小技巧,整数运算中,a/b的上取整可以用(a+b-1)/b。

#include <iostream>
#include <algorithm>

using namespace std;

const int MAX_N = 100005;

int n, k;
int time[MAX_N];

bool C(int mid) {
    int sum = 0;
    for(int i=0; i<n; i++) {
        if(time[i] > mid) {
            sum += (time[i] - mid + k - 2) / (k - 1);
            if(sum > mid)   return true;            
        }
    }

    return false;
}

int main() {

    freopen("in.txt", "r", stdin);

    while(~scanf("%d", &n)) {
        for(int i=0; i<n; i++)  scanf("%d", &time[i]);
        scanf("%d", &k);

        int l = 0;
        int u = *max_element(time, time+n);

        if(k == 1) {
            printf("%d\n", u);
            continue;   
        }

        while(l <= u) {
            //防止(l+u)超出范围 
            int mid = l + (u - l) / 2;
            if(C(mid)) {
                l = mid + 1;
            }
            else {
                u = mid - 1;
            }
        }

        printf("%d\n", u+1);
    }

    fclose(stdin);

    return 0;
}
posted @ 2016-12-27 15:10  StevenLuke  阅读(148)  评论(0编辑  收藏  举报