[蓝桥杯 2023 省 B] 冶炼金属

本文介绍了蓝桥杯2023省赛中一道关于冶炼金属的C++编程题目,重点讲解了如何使用二分查找优化解决方案,以找到满足所有记录的最小和最大金属冶炼数量。
摘要由CSDN通过智能技术生成

 

P9240 [蓝桥杯 2023 省 B] 冶炼金属 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

===============================================================

 参考题解:

#C++3150——蓝桥杯2023年第十四届省赛真题-冶炼金属(分块)-Dotcpp编程社区

https://www.bilibili.com/video/BV1wc411x7KU/?spm_id_from=333.1007.top_right_bar_window_history.content.click&vd_source=775316543df455e17016d86856ed432d

================================================================

对第一种解法做一个备忘的笔记(二分的部分放在评论区):

关于一个记录的最大v和最小v,即

 int max=a/b,min=a/(b+1);
    //对于max这个式子,求出的max肯定是合法的,max如果再大1,a不变(普通金属总量不变)那么b肯定变小,就不能冶炼出那么多金属,就不合法了;而min是除以原有冶炼数量+1,得到一个数,这个数肯定是不合法的,但是可以看成是这个冶炼数量(原有冶炼数量+1)的最大v,所以再加上1就是原有冶炼数量的最小值 。

#include<bits/stdc++.h>
#define int long long
using namespace std;
signed main(){
	int n;
	cin>>n;
	int a,b;
	cin>>a>>b;
	int max=a/b,min=a/(b+1);
	//max如果再大,a不变那么b肯定变小,就不能冶炼出那么多金属,就不合法了;而min是除以原有冶炼数量+1,得到一个数,
	//这个数肯定是不合法的,但是是这个冶炼数量的最大v,所以再加上1就是原有冶炼数量的最小值 
	n--;
	while(n--){
		cin>>a>>b;
		if(max>a/b) max=a/b;
		if(min<a/(b+1)) min=a/(b+1);
	}
	cout<<min+1<<" "<<max;
	return 0;
}

  想到二分主要是首先想到枚举v。最小的v是从1枚举到一个较大的数,然后用这个数去一一地检测是否满足每一条记录,但是这样运行时间过长。所以要考虑二分,因为v的序列是一个递增的序列,满足二分的条件,而合法的v区间满足对b[i]==a[i]/v。条件的判断也满足着线性的大小关系。比如v大到超出合法区间,总有一条记录是b[i]>a[i]/v,且v继续增大也满足这个关系。

这里要注意的是,不合法的时候是至少有一条记录不满足,而不是全部记录不满足。

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

guts350

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值