蓝桥杯省赛真题——冶炼金属

问题描述

小蓝有一个神奇的炉子用于将普通金属 O 冶炼成为一种特殊金属 X。这个炉子有一个称作转换率的属性 V,V 是一个正整数,这意味着消耗 V 个普通金属 O 恰好可以冶炼出一个特殊金属 X,当普通金属 O 的数目不足 V 时,无法继续冶炼。

现在给出了 N 条冶炼记录,每条记录中包含两个整数 A 和 B,这表示本次投入了 A 个普通金属 O,最终冶炼出了 B 个特殊金属 X。每条记录都是独立的,这意味着上一次没消耗完的普通金属 O 不会累加到下一次的冶炼当中。

根据这 N 条冶炼记录,请你推测出转换率 V 的最小值和最大值分别可能是多少,题目保证评测数据不存在无解的情况。

输入格式

第一行一个整数 N,表示冶炼记录的数目。

接下来输入 N 行,每行两个整数 A、B,含义如题目所述。

输出格式

输出两个整数,分别表示 V 可能的最小值和最大值,中间用空格分开。

输入样例

3

75 3

53 2

59 2

输出样例

20 25

cpp 复制代码
#include<bits/stdc++.h>  
#define ll long long // 定义长整型别名  
using namespace std;  
const ll N = 1e4 + 10; // 定义常数N表示数组大小  
int a[N], b[N]; // 定义两个数组a和b  
int n; // 定义变量n表示数组元素数量  
  
// 检查是否存在一个值x,使得对于所有i,b[i] < a[i] / x不成立(即找最小值时的检查函数)  
bool check_min(int mid){  
	for(int i = 0; i < n; i++){  
		if(b[i] < a[i] / mid){ // 注意这里使用的是整数除法  
			return false; // 如果存在不满足条件的i,则返回false  
		}  
	}  
	return true; // 如果所有i都满足条件,则返回true  
}  
  
// 检查是否存在一个值x,使得对于所有i,b[i] > a[i] / x不成立(即找最大值时的检查函数)  
bool check_max(int mid){  
	for(int i = 0; i < n; i++){  
		if(b[i] > a[i] / mid){ // 注意这里同样使用的是整数除法  
			return false; // 如果存在不满足条件的i,则返回false  
		}  
	}  
	return true; // 如果所有i都满足条件,则返回true  
}  
  
void solve(){  
	cin >> n; // 输入数组元素数量n  
	for(int i = 0; i < n; i++){  
		cin >> a[i] >> b[i]; // 输入数组a和b的元素  
	}  
	  
	int lmin = 1, rmin = 1e9; // 定义二分查找的左右边界,用于找最小值  
	while(lmin < rmin){ // 二分查找找最小值  
		int mid = lmin + rmin >> 1; // 计算中点  
		if(check_min(mid)){ // 如果mid满足条件(即不存在b[i] < a[i] / mid的情况)  
			rmin = mid; // 更新右边界为mid,继续向左搜索  
		}else{  
			lmin = mid + 1; // 否则,更新左边界为mid+1  
		}  
	}  
	  
	int lmax = 1, rmax = 1e9; // 定义二分查找的左右边界,用于找最大值  
	while(lmax < rmax){ // 二分查找找最大值  
		int mid = lmax + rmax + 1 >> 1; // 计算中点,注意要加1以避免死循环  
		if(check_max(mid)){ // 如果mid满足条件(即不存在b[i] > a[i] / mid的情况)  
			lmax = mid; // 更新左边界为mid,继续向右搜索  
		}else{  
			rmax = mid - 1; // 否则,更新右边界为mid-1  
		}  
	}  
	  
	cout << lmin << " " << lmax << '\n'; // 输出找到的最小值和最大值  
}  
  
signed main(){  
	ios::sync_with_stdio(0); // 取消C++和C的输入输出同步  
	cin.tie(0); // 解除cin与cout的绑定  
	cout.tie(0);  
	int t = 1; // 定义测试用例数量(这里固定为1)  
	while(t--){ // 循环处理每个测试用例  
		solve(); // 调用solve函数处理测试用例  
	}  
	return 0;  
}

二分模版整理

cpp 复制代码
// 二分查找模板的注释  
// 向左找目标值(找满足条件的最小值)  
while(l < r){  
	int mid = l + r >> 1; // 计算中点  
	if(check(mid)){ // 如果mid满足条件  
		r = mid; // 更新右边界为mid,继续向左搜索  
	}else{  
		l = mid + 1; // 否则,更新左边界为mid+1  
	}  
}  
  
// 向右找目标值(找满足条件的最大值)  
while(l < r){  
	int mid = l + r + 1 >> 1; // 为了避免死循环,当l和r相邻时mid应取r的下一位置  
	if(check(mid)){ // 如果mid满足条件  
		l = mid; // 更新左边界为mid,继续向右搜索  
	}else{  
		r = mid - 1; // 否则,更新右边界为mid-1  
	}  
}   
  
相关推荐
计算机小白一个4 小时前
蓝桥杯 Java B 组之设计 LRU 缓存
java·算法·蓝桥杯
万事可爱^5 小时前
HDBSCAN:密度自适应的层次聚类算法解析与实践
算法·机器学习·数据挖掘·聚类·hdbscan
黑不溜秋的5 小时前
C++ 设计模式 - 策略模式
c++·设计模式·策略模式
欧了1116 小时前
洛谷P9240 [蓝桥杯 2023 省 B] 冶炼金属
职场和发展·蓝桥杯·洛谷·蓝桥杯大学b组c语言
大数据追光猿7 小时前
Python应用算法之贪心算法理解和实践
大数据·开发语言·人工智能·python·深度学习·算法·贪心算法
Dream it possible!7 小时前
LeetCode 热题 100_在排序数组中查找元素的第一个和最后一个位置(65_34_中等_C++)(二分查找)(一次二分查找+挨个搜索;两次二分查找)
c++·算法·leetcode
夏末秋也凉7 小时前
力扣-回溯-46 全排列
数据结构·算法·leetcode
南宫生7 小时前
力扣每日一题【算法学习day.132】
java·学习·算法·leetcode
柠石榴7 小时前
【练习】【回溯No.1】力扣 77. 组合
c++·算法·leetcode·回溯
Leuanghing7 小时前
【Leetcode】11. 盛最多水的容器
python·算法·leetcode