hdu 周正虎的难题

周正虎的难题

Problem Description

自从周正虎被告知山上并没有老虎后就成为了当地一名伐木工人。这一次他需要砍下M米的木材,当然,自从有了新的伐木工具之后,这对他来说简直就是一件轻而易举的事情。
周正虎的伐木工具的使用说明书上这样写道:机器需要设定一个高度参数H(米),然后机器就会升高到H(米),砍下所有高于H(米)的树。对于高度没有达到H(米)的树,我们认为它是幸运的,在这次砍伐中它将免受威胁。例如:现有树的高度为 20, 15, 10, 17 将机器设置为15,那么我们将砍伐到第一和第四棵树,得到的木材长度为(20-15) + (17-15) = 7。
周正虎是一个爱好环境的人,所以他想知道他最高能将机器的高度设置为多少去满足至少砍下M米的木材。

Input

输入有多组数据。第一行将输入两个数据,1 <= N <= 1 000 000,1<= M <= 2 000 000 000分别代表树的棵树以及要得到的木材的长度,
第二行将包含以空格隔开的N个数,分别表示第1到第N棵树的高度。每棵树的高度小于 1 000 000 000,树的高度总和将超过M,周正虎将始终得到他想要的木材长度。

Output

输出有且仅有一行,表示要求输出的高度。

Sample Input

4 7
20 15 10 17
5 20
4 42 40 26 46

Sample Output

15
36

Source

2012暑假集训
题意:求最大的h是的截取的长度至少为M
AC代码:
 

#include <stdio.h>
#include <iostream>
using namespace std;
#define maxn 1011111
#define ll long long
const int MM = 2000000000;
ll a[maxn];
ll N,M;
ll sum( ll h)
{
ll s=0;
for( int i=1;i<=N;i++)
{
if(a[i]<=h) continue;
s += (a[i]-h);
if(s >= MM) return MM;
}
return s;
}
int main ( )
{
while(scanf("%I64d%I64d",&N,&M)!=EOF)
{
ll max=0;
for( int i=1;i<=N;i++)
{
scanf("%I64d",&a[i]);
if(max<a[i]) max=a[i];
}
ll l=0,r=max;
ll mid=l, ans=l;
while( l<r )
{
mid=(l+r)/2;
if(sum(mid)>=M)//mid符合要求那么<=mid的h都能使截取长度至少为M,那么再往上点是否符合,故此步判断
{
ans = mid;
l=mid+1;
}
else r=mid;//mid不符合要求那么>mid的h都不能使截取长度至少为M,那么再往下点是否符合,故此步判断
}
printf("%I64d\n",ans);
}
return 0;
}

链接:http://acm.hdu.edu.cn/diy/contest_showproblem.php?pid=1006&cid=16309&hide=0

posted @ 2012-07-24 17:13  jiai  Views(224)  Comments(0Edit  收藏  举报