一、题目:

二、题解:
1、思路解析:
1)首先我们可以发现题目的样例数量为( n < = 1000 n<=1000 n<=1000),因此我们可以考虑 O ( n ∗ l o g n ) O(n*log^n) O(n∗logn)时间复杂度的算法

2)通过观察题目我们可以发现,要求我们求解答案的最小值与最大值,且答案拥有一定的单调性
3)因此我们的第一个思想是用二分答案求解:
2、二分答案详细过程:
1)找变量关系,判断合法区间
- 通过画图我们发现,当转化率 V V V不断增加时, b [ i ] b[i] b[i]的变化如下,虽然一整段 b [ i ] b[i] b[i]的值单调性,但是我们可以对其进行分段
- 二分: a [ i ] / x < = b [ i ] a[i]/x<=b[i] a[i]/x<=b[i]的区间,求解最小值(蓝色区间)
- 二分: a [ i ] / x > = b [ i ] a[i]/x>=b[i] a[i]/x>=b[i]的区间,求解最大值(红色区间)
2)判断区间端点
1^#^ 找最小值
- 二分函数构建
- 此时,我们发现其合法区间为 < = b [ i ] <=b[i] <=b[i](因为我们要使得我们想要求解的最值处于划分的区间边界)
- 因此 我们可以通过判断 a [ i ] / x a[i]/x a[i]/x的值来判断是否合法(最后
return r
)
cpp
//合法区间<=b[i]的值
bool check_min(ll x) //x表示当前的转化率
{
for(ll i=1;i<=n;i++)
{
if(a[i]/x>b[i]) return false;
}
return true;
}
- 二分入口构建
- 当
check_min(mid)
成立时,说明此时 a [ i ] / x < = b [ i ] a[i]/x<=b[i] a[i]/x<=b[i], m i d mid mid偏大,因此r=mid
- 最后
reutrn r
即可(如图所示, r r r所指向的部分为答案)
- 当
cpp
ll l = 1, r = 1e9 + 7;
while(l+1<r) //二分答案找最满足条件的最小值
{
ll mid=(l+r)>>1;
if(check_min(mid)) r=mid;
else l=mid;
}
v_min=r;
2^#^找最大值
- 二分函数构建
- 此时,我们发现其合法区间为 > = b [ i ] >=b[i] >=b[i](因为我们要使得我们想要求解的最值处于划分的区间边界)
- 因此 我们可以通过判断 a [ i ] / x a[i]/x a[i]/x的值来判断是否合法(最后
return L
)
cpp
bool check_max(ll x) //合法区间>=b[i]的值
{
for(ll i=1;i<=n;i++)
{
if(a[i]/x<b[i]) return false;
}
return true;
}
- 二分入口构建
- 当
check_min(mid)
成立时,说明此时 a [ i ] / x > = b [ i ] a[i]/x>=b[i] a[i]/x>=b[i], m i d mid mid偏小,因此l=mid
- 最后
reutrn l
即可(如图所示, l l l所指向的部分为答案)
- 当
cpp
l=1,r=1e9+7;
while(l+1<r) //二分答案找满足条件的最大值
{
ll mid=(l+r)>>1;
if(check_max(mid)) l=mid;
else r=mid;
}
v_max=l;
3、完整代码解析:
cpp
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 7;
ll a[N], b[N], n;
//合法区间<=b[i]的值
bool check_min(ll x) //x表示当前的转化率
{
for(ll i=1;i<=n;i++)
{
if(a[i]/x>b[i]) return false;
}
return true;
}
bool check_max(ll x) //合法区间>=b[i]的值
{
for(ll i=1;i<=n;i++)
{
if(a[i]/x<b[i]) return false;
}
return true;
}
int main() {
cin >> n;
ll v_min,v_max;
for (int i = 1; i <= n; i++)
{
cin >> a[i] >> b[i];
}
//转化率V->:不断增加 Vmin Vmax
//结果:>b[i] >b[i] >b[i] =b[i] =b[i] =b[i] <b[i] <b[i] <b[i]
ll l = 1, r = 1e9 + 7;
while(l+1<r) //二分答案找最满足条件的最小值
{
ll mid=(l+r)>>1;
if(check_min(mid)) r=mid;
else l=mid;
}
v_min=r;
l=1,r=1e9+7;
while(l+1<r) //二分答案找满足条件的最大
{
ll mid=(l+r)>>1;
if(check_max(mid)) l=mid;
else r=mid;
}
v_max=l;
cout << v_min << ' ' << v_max;
return 0;
}