题解 P4058 [Code+#1]木材

前言

这什么题啊,不就是个二分答案我从65到100都经历了一遍……(瞬间气哭)

\(\sf {Solution}\)

题目理解起来不难的,大意就懒得写了。

一眼二分答案。

此题属于在形如 \(\{0,0,0....1,1,1,\}\) 的序列中查找第一个 \(1\) 的题型。

算法流程:

  1. 初始化 \(l=0,r=inf\)\(r\) 尽可能大)。
  2. 如果 \(l=r\) ,停止循环。
  3. 计算中点 \(mid=\left\lfloor\dfrac{l+r}{2}\right\rfloor\)
  4. 若等待 \(mid\) 个月满足条件, \(r=mid\)
  5. 否则 \(l=mid+1\)
  6. 回到2。

至于如何判断是否满足条件,写一个函数check一下就珂以了啦~

\(\sf {P.S.}\)

什么都要开unsigned long long,否则会WA的很惨。

\(\sf {Code}\)

#include<cstdio>
using namespace std;
unsigned long long n,s,k,mid,a[200005],h[200005];
bool check(unsigned long long x)
{
	unsigned long long ans=0;
	for(unsigned long long i=1;i<=n;++i)
		if(h[i]+x*a[i]>=k)//超过要求高度的树计算在总长度范围内
			ans+=h[i]+x*a[i];
	if(ans>=s)
		return true;
	return false;//如果满足订单需求就返回true
}
int main()
{
	scanf("%lld%lld%lld",&n,&s,&k);
	for(int i=1;i<=n;++i)
		scanf("%lld",&h[i]);
	for(int i=1;i<=n;++i)
		scanf("%lld",&a[i]);
	unsigned long long l=0,r=10000000000000000;//l和r的初始化
	while(l<r)
	{
		mid=(l+r)/2;
		if(check(mid))
			r=mid;
		else l=mid+1;
	}//二分
	printf("%lld",l);//输出结果
	return 0;
}
posted @ 2020-08-17 16:31  Callous_Murder  阅读(218)  评论(0编辑  收藏  举报