哈喽,各位小伙伴们大家好😀😀😀。今天给大家带来2023年蓝桥杯的b组真题--治炼金属。
总体的思路是用二分来写的。
题目描述
小蓝有一个神奇的炉子用于将普通金属 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
提示
当 V = 20 时,有:⌊75/20⌋ = 3,⌊ 53/20 ⌋ = 2,⌊ 59/20 ⌋ = 2,可以看到符合所有冶炼记录。
当 V = 25 时,有:⌊75/25⌋ = 3,⌊ 53/25 ⌋ = 2,⌊ 59/25 ⌋ = 2,可以看到符合所有冶炼记录。
且再也找不到比 20 更小或者比 25 更大的符合条件的 V 值了。
对于 30% 的评测用例,1 ≤ N ≤ 10^2。
对于 60% 的评测用例,1 ≤ N ≤ 10^3。
对于 100% 的评测用例,1 ≤ N ≤ 10^4,1 ≤ B ≤ A ≤ 10^9。
解题思路:我们可以先假设最小转化率位v_min,最大转化率位v_max。我们可以知道转化率小于v_min的转化率,它们对应的B的值将大于确定的值。而转化率大于v_max,它们对应的B的值将小于确定的值。示意图如下:
具体确定最大值和最小值可以通过二分查找,左边满足右边不满足或者左边不满足右边满足。不断缩小取值空间。具体的代码如下:
#include<bits/stdc++.h>
using namespace std;
const long int Max=1e4+1;
int n;//冶炼记录的数目
int a[Max],b[Max];
bool check_min(int v)
{
for(int i=1;i<=n;i++)
if(a[i]/v>b[i]) return 0;//满足的是小于等于b[i]
return 1;
}
bool check_max(int v)
{
for(int i=1;i<n;i++)
{
if(a[i]/v<b[i]) return 0;//满足的是大于等于b[i]
}
return 1;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i]>>b[i];
}
long int L=1,R=100000000,v_min;
while(L<=R)
{
int mid=(L+R)/2;
if(check_min(mid))//大于等于v满足
{
v_min=mid;
R=mid-1;
}
else
{
L=mid+1;
}
}
L=1,R=100000000;//要重新赋值
int v_max;
while(L<=R)
{
int mid=(L+R)/2;
if(check_max(mid))
{
v_max=mid;
L=mid+1;
}else
{
R=mid-1;
}
}
cout<<v_min<<" "<<v_max;
}
代码运行结果如下:
好啦!!!以上是本篇博客的全部内容。喜欢的记得点赞+收藏+关注。接下来小编还会继续更新关于蓝桥杯的内容。
祝大家每天开心,天天进步。😁😁😁