题目描述
小蓝有一个神奇的炉子用于将普通金属 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 时,有:\left\lfloor \dfrac{75}{20} \right\rfloor=3,\left\lfloor \dfrac{53}{20} \right\rfloor=2,\left\lfloor \dfrac{59}{20} \right\rfloor=2,可以看到符合所有冶炼记录。 当 V=25 时,有:\left\lfloor \dfrac{75}{25} \right\rfloor=3,\left\lfloor \dfrac{53}{25} \right\rfloor=2,\left\lfloor \dfrac{59}{25} \right\rfloor=2,可以看到符合所有冶炼记录。 且再也找不到比 20 更小或者比 25 更大的符合条件的 V 值了。
评测用例规模与约定
对于 30% 的评测用例,1 \le N \le 10^2。 对于 60% 的评测用例,1 \le N \le 10^3。 对于 100% 的评测用例,1 \le N \le 10^4,1 \le B \le A \le 10^9。
凝练一下题目,就是a个O金属可以炼成b个X金属,这其中的转化率V是一个整数,这个数V代表着V个O可以转化成1个X,不为V的倍数多出来的O不参与金属冶炼也不会积累,现在有n组a,b数据,要求V的最小值和最大值,通过样例说明可以知道V是适用于所有数据的V的最大值和最小值
下面进行分析,题目红色区域我们知道了,当A/V是向下取整取到B的,如果A不是V的倍数,那么会有下面的关系
B \le \frac{A}{V} < B+1拆开成两个不等式有
- \boldsymbol{\dfrac{A}{V}\ge B}
- \boldsymbol{\dfrac{A}{V}< B+1}
等式2移项可得
V > \frac{A}{B+1}这个式子代表的是V是大于在增加一个B情况下的产出的,如果说a/(b+1)在数学上不是整数,那它在C语言中会被向下取整,假如是19.666,有
V > 19.666V是整数,只可能取20及以上的数,即等价于
V \ge 19 + 1所以公式:
\boldsymbol{V \ge \left\lfloor \frac{A}{B+1} \right\rfloor + 1}等式1移项可得
V \le \frac{A}{B}两者结合就能得到V的关键表达式
A/(B+1) +1 <= V <= A/B
用循环遍历每一份数据,求得它的左右两边的值,因为V的最大值和最小值是对于全部数据的,所以
最大值应该是全部数据最大值中最小的那一个(上确界),最小值应该是全部数据最小值中最大的那一个(下确界)
所以代码如下所示
#include <stdio.h>
int main(void)
{
int N;
scanf("%d", &N);
long long low = 0;
long long high = 1e18;
long long A, B;
for(int i = 0; i < N; i++)
{
scanf("%lld %lld", &A, &B);
long long L = A / (B + 1) + 1;
long long R = A / B;
if(L > low) low = L;
if(R < high) high = R;
}
printf("%lld %lld\n", low, high);
return 0;
}
评论(0)
暂无评论