您的位置:首页 > 其它

POJ3104 Drying [二分]

2016-01-09 15:16 489 查看
题目不是非常难

大体思路:

题意:烘干机,给出一堆衣服的水分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;

犯了一个非常2的错误,ceil(int/int),应该是ceil(int*1.0/int)

再次验证我的二分写法没错,哇哈哈哈

标准的

while l<r

l=mid+1;

r=mid;

mid=l+(r-l)/2;

代码例如以下

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

long long num[111111];
int main()
{
//cout<<"here"<<endl;
//cout<<ceil(3.4)<<endl;
//cout<<ceil(4)<<endl;
//cout<<"end"<<endl;
long long n,k;
long long maxn=0;
while(scanf("%lld",&n)!=EOF)
{
for(long long i=1;i<=n;i++)
{
scanf("%lld",&num[i]);
maxn=max(maxn,num[i]);
}
sort(num+1,num+1+n);
scanf("%lld",&k);
if(k==1)
{
printf("%lld\n",maxn);
continue;
}
long long l=1,r=maxn,mid=(r+l)/2;
long long ans=0;
while(l<r)
{
//mid=(l+r)/2;
long long sum=0;
for(long long i=1;i<=n;i++)
{
if(num[i]>mid)
sum+=ceil((num[i]-mid)*1.0/(k-1));
}
if(sum>mid)
l=mid+1;
else if(sum<=mid)
{
r=mid;
}
mid=(l+r)/2;
}
printf("%lld\n",mid);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: