洛谷P1873 砍樹
阿新 • • 發佈:2019-01-06
題目描述
伐木工人米爾科需要砍倒M米長的木材。這是一個對米爾科來說很容易的工作,因為他有一個漂亮的新伐木機,可以像野火一樣砍倒森林。不過,米爾科只被允許砍倒單行樹木。
米爾科的伐木機工作過程如下:米爾科設定一個高度引數H(米),伐木機升起一個巨大的鋸片到高度H,並鋸掉所有的樹比H高的部分(當然,樹木不高於H米的部分保持不變)。米爾科就行到樹木被鋸下的部分。
例如,如果一行樹的高度分別為20,15,10和17,米爾科把鋸片升到15米的高度,切割後樹木剩下的高度將是15,15,10和15,而米爾科將從第1棵樹得到5米,從第4棵樹得到2米,共得到7米木材。
米爾科非常關注生態保護,所以他不會砍掉過多的木材。這正是他為什麼儘可能高地設定伐木機鋸片的原因。幫助米爾科找到伐木機鋸片的最大的整數高度H,使得他能得到木材至少為M米。換句話說,如果再升高1米,則他將得不到M米木材。
輸入輸出格式
輸入格式:
第1行:2個整數N和M,N表示樹木的數量(1<=N<=1000000),M表示需要的木材總長度(1<=M<=2000000000)
第2行:N個整數表示每棵樹的高度,值均不超過1000000000。所有木材長度之和大於M,因此必有解。
輸出格式:
第1行:1個整數,表示砍樹的最高高度。
輸入輸出樣例
輸入樣例#1: 複製
5 20
4 42 40 26 46
輸出樣例#1: 複製
36
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<queue>
#include<algorithm>
#include<bits/stdc++.h>
#define N 1000009
using namespace std;
long long l;
long long r;
long long n,m;
long long a[N];
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
r=max(r,a[i]);
}
while (l<=r)
{
int mid=(l+r)>>1;
long long ans=0;
for(int i=1;i<=n;i++)
if(a[i]>mid)ans+=a[i]-mid;
if(ans<m)r=mid-1;
else l=mid+1;
}
printf("%d",l-1);
}
#include<bits/stdc++.h>
long long a[1000009];
long long n,m;
long long sum;
long long ans;
using namespace std;
int main()
{
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
sort(a+1,a+1+n);
int i=n;
while(sum<m)
{
sum+=(a[i]-a[i-1])*(n-i+1);
i--;
}
i++;
ans=a[i-1]+(sum-m)/(n-i+1);
printf("%lld",ans);
}