cogs luogu 砍树

★   输入文件:eko.in   输出文件:eko.out   简单对比
时间限制:1 s   内存限制:256 MB

【题目描述】

N棵树,每棵都有一个整数高度。有一个木头的总需要量M。

现在确定一个最大的统一的砍树高度H,如果某棵树的高度大于H,则高出的部分被砍下。使得所有被砍下的木材长度之和达到M(允许稍超过M)。

例如,有4棵树,高度分别是20 15 10 17, 需要的木材长度为 7,砍树高度为15时,第1棵树被砍下5,第4棵树被砍下2,得到的总长度为7。如果砍树高度为16时,第1棵树被砍下4,第4棵树被砍下1,则得到的木材数量为5。

【输入格式】

第1行:2个整数N和M,N表示树木的数量(1 ≤ N ≤ 1 000 000),M表示需要的木材总长度(1 ≤ M ≤ 2 000 000 000)。

第2行: N个整数表示每棵树的高度,值均不超过1  000  000  000。所有木材高度之和大于M,因此必然有解。

【输出格式】

第1行:1个整数,表示砍树的最高高度。

【样例输入】

5 20
4 42 40 26 46

【样例输出】

36
 1 #include<iostream>
 2 #include<cstdio>
 3 
 4 #define ll long long
 5 using namespace std;
 6 const int N=1000010;
 7 
 8 ll a[N];
 9 ll n,m;
10 
11 inline ll read()
12 {
13     ll x=0;
14     char c=getchar();
15     while(c<'0'||c>'9')c=getchar();
16     while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
17     return x;
18 }
19 
20 inline bool pd(int now)
21 {
22     ll answer=0;
23     for(int i=1;i<=n;i++)
24         if(a[i]-now>0)answer+=(a[i]-now);
25     if(answer>=m)return 1;
26     else return 0;
27 }
28 
29 int main()
30 {
31     freopen("eko.in","r",stdin);
32     freopen("eko.out","w",stdout);
33     n=read();
34     m=read();
35     ll r=-1;
36     for(int i=1;i<=n;i++)
37     {
38         a[i]=read();
39         r=max(r,a[i]);
40     }    
41     
42     ll l=1;
43     ll mid;
44     while(l<r)
45     {
46         mid=(r-l)/2+l;
47         if(pd(mid))l=mid+1;
48         else r=mid;
49     }
50     printf("%lld",l-1);
51     return 0;
52 }
原文地址:https://www.cnblogs.com/lyqlyq/p/7044668.html