原题网址
由于某些原因,这个网址会进不去…
题目描述
m
x
y
mxy
mxy被小
w
w
w叫去砍树了。
m
x
y
mxy
mxy需要砍倒
M
M
M米长的木材。现在
m
x
y
mxy
mxy弄到了一个奇怪的伐木机。
m
x
y
mxy
mxy的伐木机工作过程如下:
m
x
y
mxy
mxy设置一个高度参数
H
H
H(米),伐木机升起一个巨大的锯片到高度
H
H
H,并锯掉所有的树比
H
H
H高的部分(当然,树木不高于
H
H
H米的部分保持不变)。
m
x
y
mxy
mxy就得到树木被锯下的部分。
例如,如果一行树的高度分别为
20
,
15
,
10
20,15,10
20,15,10和
17
17
17米,
m
x
y
mxy
mxy把锯片升到
15
15
15米的高度,切割后树木剩下的高度将是
15
,
15
,
10
15,15,10
15,15,10和
15
15
15米,而
m
x
y
mxy
mxy将从第
1
1
1棵树得到
5
5
5米,从第
4
4
4棵树得到
2
2
2米,共得到
7
7
7米木材。
m
x
y
mxy
mxy非常关注生态保护,所以
t
a
ta
ta不会砍掉过多的木材。这正是
t
a
ta
ta为什么要尽可能高地设定伐木机锯片的原因。帮助
m
x
y
mxy
mxy找到伐木机锯片的最大的整数高度
H
H
H,使得
t
a
ta
ta能得到的木材至少为
M
M
M米。换句话说,如果再升高
1
1
1米,则
t
a
ta
ta将得不到
M
M
M米木材。
格式
输入格式
第
1
1
1行:
2
2
2个整数
N
N
N和
M
,
N
M,N
M,N表示树木的数量(
1
≤
N
≤
1
000
000
1\le N\le1\ 000\ 000
1≤N≤1 000 000),M 表示需要的木材总长度(
1
≤
M
≤
2
000
000
000
1\le M\le2\ 000\ 000\ 000
1≤M≤2 000 000 000)。
第
2
2
2行:
N
N
N个整数表示每棵树的高度,值均不超过
1
000
000
000
1\ 000\ 000\ 000
1 000 000 000。保证所有木材长度之和大于
M
M
M,因此必然有解。
输出格式
一行 1 1 1个整数,表示砍树的最高高度。
样例
输入样例
5 20
4 42 40 26 46
输出样例
36
解题思路
这道题非常明显可以用二分算法。当砍到mid层时,如果大于要求的木材长度,就再砍高一点;反之,则砍低一点。直到求出最优解。并且本题也不需要使用高精度。
Code
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<ctime>
#include<cstring>
#include<string>
#include<map>
#include<queue>
#define maxn 1000000 // 作者标准设置
using namespace std;
long long n, m, a[maxn + 1], ans, maxh;
void init() // 在此执行预处理
{
cin>>n>>m;
for (int i = 1; i <= n; i ++)
{
cin>>a[i];
if (a[i] > maxh) maxh = a[i];
}
}
void comp()
{
long long s, l = 1, r = maxh - 1, mid; // 定义二分算法变量
while (l <= r) // 二分算法
{
s = 0;
mid = (l + r + 1) / 2;
for (int i = 1; i <= n; i ++) if (a[i] > mid) s += a[i] - mid;
if (s >= m) l = mid + 1;
else r = mid - 1;
}
ans = (l + r) / 2;
}
void oput() // 在此输出总结果
{
cout<<ans;
}
int main()
{
ios::sync_with_stdio(false); // 加快输入输出速度
init();
comp();
oput();
return 0;
}
大功告成 ∼ \sim ∼