题目大意:
有时很难晾干洗完的衣服特别是在冬天的时候,聪明的Jane使用暖气片来使该过程变得更快,由于暖气片很小,一次只能处理一件衣服,但是能使衣服干得更加快。
现有多个测例(测例数无上限),每个测例中都有n件衣服(1 ≤ n ≤ 100,000),并会给出每件衣服的湿度ai(表示第i件衣服的湿度,1 ≤ ai ≤ 10^9),自然干的话每分钟可以干一单位水分,接下来会告诉你暖气片的能力k,即每分钟使用暖气片可以干掉一件衣服多少水分(1 ≤ k ≤ 10^9),对于每个测例输出弄干这些衣服的最小耗时(分钟数)。
注释代码:
/*
* Problem ID : POJ 3104 Drying
* Author : Lirx.t.Una
* Language : GCC
* Run Time : 704 ms
* Run Memory : 752 KB
*/
#pragma GCC optimize("O2")
#include <stdio.h>
#include <math.h>
//maximum number of clothes
//衣服的最大数量
#define MAXCLOTN 100000
typedef long long llg;//试探的时候可能会超出int的范围
int w[MAXCLOTN];//wet value,记录每件衣服的湿度
int
main() {
int n;//衣服数量
int i;//计数变量
int k;//吹风机的能力
//用[lft, rht]表示所花时间的可能区间
//mid为时间区间的中点值
//就是在该区间上使用二分搜索得出正确的最小值
int lft, rht, mid;
llg rt;//radiator's time,吹风机所花的时间
//思路:由于衣服干只有两种贡献过程,一部分是自然干
//另一部分是吹风机的功劳,弄干衣服的总时间必然等于
//吹风机工作时间(因为如果吹风机工作时间小于干的总时间
//那就意味着必然有一段时间衣服实在自然干而没有利用吹风机
//这种情况是不合理的),假设弄干衣服的总时间为mid,则对于
//湿度小于等于mid的衣服可以不用吹风机而自然干,对于湿度大于
//mid的衣服,设使用吹风机处理的时间为x,自然干的时间为y
//则由ai ≤ x * k + y和x + y ≤ mid这两个不等式可得
//min(x) = ceil( (ai - mid) / (k - 1) )
//将各个x时间相加,如果总和大于mid表示mid不可行,否则mid是可行的
//如果mid可行则继续探索更小的值,否则就表示mid太小了需探索更大的值才行
int ans;
int max;//maximum drying time,可能的最大晾干时间
while ( ~scanf("%d", &n) ) {
for ( max = 0, i = 0; i < n; i++ ) {
scanf("%d", w + i);
if ( w[i] > max )
max = w[i];
}
scanf("%d", &k);
if ( 1 == k ) {//如果吹风机和自然干一样则直接去最大值即可
printf("%d\n", max);
continue;
}
//假设弄干总时间的范围为[1, max]
lft = 1;
rht = max;
while ( lft <= rht ) {
mid = ( lft + rht ) >> 1;
rt = 0;
for ( i = 0; i < n; i++ )
if ( w[i] > mid )
rt += (llg)ceil( (double)( w[i] - mid ) / (double)( k - 1 ) );
if ( rt <= (llg)mid ) {//表示可行
//当mid值太小时,吹风机的压力颇大,因此可能会导致rt超出int范围
//因此rt使用64位int,因此需要注意类型转换
//否则会导致损失精度得到错误答案
ans = mid;
rht = mid - 1;//探索更小值
}
else
lft = mid + 1;//不可行则要探索更大的值
}
printf("%d\n", ans);
}
return 0;
}
无注释代码:
#pragma GCC optimize("O2")
#include <stdio.h>
#include <math.h>
#define MAXCLOTN 100000
typedef long long llg;
int w[MAXCLOTN];
int
main() {
int n;
int i;
int k;
int lft, rht, mid;
llg rt;
int ans;
int max;
while ( ~scanf("%d", &n) ) {
for ( max = 0, i = 0; i < n; i++ ) {
scanf("%d", w + i);
if ( w[i] > max )
max = w[i];
}
scanf("%d", &k);
if ( 1 == k ) {
printf("%d\n", max);
continue;
}
lft = 1;
rht = max;
while ( lft <= rht ) {
mid = ( lft + rht ) >> 1;
rt = 0;
for ( i = 0; i < n; i++ )
if ( w[i] > mid )
rt += (llg)ceil( (double)( w[i] - mid ) / (double)( k - 1 ) );
if ( rt <= (llg)mid ) {
ans = mid;
rht = mid - 1;
}
else
lft = mid + 1;
}
printf("%d\n", ans);
}
return 0;
}
单词解释:
Jane:人名,简
dry:adj, 干的; vt, 把...弄干
radiator:n, 暖气片,辐射体
minimal:adj, 最低的,最小限度的
maximal:adj, 最高的,最大限度的
pack:vt, 包装,打包; n, 包装,背包
resulting:adj, 作为结果的
subregion:n, 子区域,附属区域