题意:
最让HSQ学长头疼的就是洗衣服了。洗完之后,每件衣服都有一定单位水分,在不使用烘干器的情况下,每件衣服每分钟自然流失1个单位水分,但如果使用了烘干机则每分钟流失K个单位水分。令人遗憾是HSQ所在的宿舍楼只有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
我的思路:
一开始我假设没有吹风机,所以如果自然流失,就是水分最大的干的时间,有了吹风机后,也就每次用吹风机吹过后找到最大水分的,当最大水分为0时,用的时间就为所求时间,显然需要多次快排,会超时.
AC思路:
设最小时间为mid,最好的方案就是先用吹风机吹,再自然风干。我们设用吹风机吹了num次(也就是用了num分钟),自然风干的时间就是mid-num,则 mid-num+num*m>=a[i],m是吹风机吹一次能够减少的水分。整理得到 num=(a[i]-mid)/(m-1),但这里我们要注意,当m=1时会出问题,则刚开始时我们将m–,那么式子就变为了 (a[i]-mid)/m,特判当m-1=0时,即吹风机和自然风干的效果是一样时,最少的时间就是含水量最大的那件衣服。
AC代码:
#include<bits/stdc++.h>
using namespace std;
-
#define maxn 100100 #define ll long long int n; ll a[maxn],k; bool C(ll mid)//计算使用吹风机的时间 { ll sum=0; for(int i=0;i<n;i++){ if(a[i]>mid){ sum+=(a[i]-mid)/k; if((a[i]-mid)%k)//取整的做法,因为存在小数 sum++; if(sum>mid) return false; } } return true; } int main() { while(scanf("%d",&n)!=EOF) { ll big=0,ans; for(int i=0;i<n;i++){ scanf("%lld",&a[i]); big=big>a[i]?big:a[i]; } scanf("%lld",&k); if(k==1){ printf("%lld\n",big); continue; } ll left=1,right=big; ll mid; k--; while(left<=right) { mid=(right-left)/2+left; if(C(mid)) right=mid-1,ans=mid; else left=mid+1; } printf("%lld\n",ans); } return 0; }