while(l<=r)
{
int mid=(l+r)/2;
if(check(mid))
{
ans=mid;
l=mid+1;
}
else
{
r=mid-1;
}
}
https://www.luogu.com.cn/problem/P1873
伐木工人米尔科需要砍倒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
本题中,check的检查内容即为 所得到的树的高度总和 是否符合题目
#include
#include
using namespace std;
int n,m;
int ans=0;
int l=0,r=0;
int tree[1000005]={
0};//注意数据范围
bool check(int x)
{
long long s=0;//注意数据范围
for(int i=1;i<=n;i++)
{
if(tree[i]>x)//判断第i棵的高度是否比锯片的高度高
{
s+=tree[i]-x;//将树砍下的高度累加
}
}
return s>=m;//将高度和与需求高度m比较
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>tree[i];
r=max(r,tree[i]);//存放最大值!
}
while(l<=r)//简单的对半查找
{
int mid=(l+r)/2;
if(check(mid))
{
?;
l=?;
}
else
{
r=?;
}
}
cout<<ans;//完美输出!
return 0;
}
搞定一题,下一题:
https://www.luogu.com.cn/problem/P2440
要保护环境
木材厂有一些原木,现在想把这些木头切割成一些长度相同的小段木头(木头有可能有剩余),需要得到的小段的数目是给定的。当然,我们希望得到的小段木头越长越好,你的任务是计算能够得到的小段木头的最大长度。木头长度的单位是cm。原木的长度都是正整数,我们要求切割得到的小段木头的长度也是正整数。
例如有两根原木长度分别为11和21,要求切割成到等长的6段,很明显能切割出来的小段木头长度最长为5.
第一行是两个正整数N和K(1 ≤ N ≤ 100000,1 ≤ K ≤ 100000000),N是原木的数目,K是需要得到的小段的数目。
接下来的N行,每行有一个1到100000000之间的正整数,表示一根原木的长度。
能够切割得到的小段的最大长度。如果连1cm长的小段都切不出来,输出”0”。
输入 #1
3 7
232
124
456
输出 #1
114
此题中,check用来判断 被切割的段数是否符合题目要求
#include
#include
using namespace std;
int n,k;//N是原木的数目,K是需要得到的小段的数目
int treelen[100005]={
0};
int l=0,r=0;
int ans=0;
bool check(int x)
{
int s=0;
for(int i=1;i<=n;i++)
{
if(x<=treelen[i]&&x!=0)//若能切割且切割长度>=1
{
s+=(treelen[i]/x);//段数
}
else if(x==0)//无法切割(长度<1)
{
return s=0;//无法切割即段数为0
}
}
return s>=k;//返回条件!!!!
}
int main()
{
cin>>n>>k;
for(int i=1;i<=n;i++)
{
cin>>treelen[i];
r=max(r,treelen[i]);//存放最大值
}
while(l<=r)//简单的对半查找
{
int mid=(l+r)/2;
if(check(mid))
{
?;
l=?;
}
else
{
r=?;
}
}
cout<<ans;//完美输出
return 0;
}