Poj 3104 Drying 二分

题目链接: 点击打开链接
题意:n件湿衣服,每件衣服含水量为x,正常放置晾干法,每分钟湿衣服的含水量 - 1,吹风机吹干法,每分钟湿衣服的含水量 - k。吹风机只有一台。
问让所有湿衣服晾干最短需要多长时间。
题解:一个一个枚举绝对超时,不妨换个思路,他的晾干时常的区间为【1,max含水量】,我们可以二分枚举这个时间,然后小于这个时长的让他自然烘干,大于的让他吹风机烘干,为什么呢?

因为若总耗时大约我们二分枚举的时间话,说明最短时间一定偏大,反过来的话就是偏小。
我们再思考一个非常重要的问题,我们在用吹风机吹干某个衣服时,其他的衣服这时候不会闲着,也会自动风干。那么问题就来了,如何让二者的同时进行?for循环去一一减一么?很明显会超时。那么我们换一个思路,用吹风机吹,是不是就相当于在自然风干的基础上额外每分钟多风干(k-1)。那么我们直接减掉我们二分枚举的时间(也就是看成让他自然风干,在自然风干的基础上额外风干(k-1)的水量)。然后二者相除,累加就是结果。这点不好想,就是这道题的经典所在。希望大家多思考思考。
代码如下

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<cmath>
using namespace std;

const int MAXN = 1e5+ 10;
long long num[MAXN];

int main(){
	int n;
	while(~scanf("%d",&n)){
		long long maxvalue = 0;
		memset(num,0,sizeof(num));
		for(int i = 0 ; i < n ; i ++){
			scanf("%lld",&num[i]);
			maxvalue = max(num[i],maxvalue);
		}
		long long k;
		scanf("%lld",&k);
		if(k == 1){
			printf("%lld\n",maxvalue);
			continue;
		}
		long long lp = 1,ans = 0,rp = maxvalue;
		while(lp <= rp){
			long long mid = (lp + rp) / 2,sum = 0;
			for(int i = 0 ; i < n ; i ++){
				if(num[i] > mid){
					long long xx = ceil((num[i] - mid) * 1.0 /(k-1));
					sum += xx;
				}
			}
			if(sum <= mid){
				ans = mid;
				rp = mid - 1;
			}
			else 
				lp = mid + 1;
		}
		printf("%lld\n",ans);
	}
}
科普

使用floor函数。floor(x)返回的是小于或等于x的最大整数。
如:     floor(10.5) == 10    floor(-10.5) == -11


使用ceil函数。ceil(x)返回的是大于x的最小整数。
如:     ceil(10.5) == 11    ceil(-10.5) ==-10

    
floor()是向负无穷大舍入,floor(-10.5) == -11;
ceil()是向正无穷大舍入,ceil(-10.5) == -10

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值