贼简单的一道二分题,非常适合初学者练习二分——简单的二分题目要二分的量通常就是题目中要求解的结果。
题目中让我们去求解转换率V可能的最大值与最小值,很明显就是一道对要求的结果(转换率V)进行二分的题目。
既然已经确定了我们要二分的量V,那么接下来就要着手考虑二分的判断条件,即需要什么样的条件才能我们要二分的量的所有数值分成两个部分。
二分的判断条件通常是通过列出有关要二分的量和其他变量之间的关系方程:
Ai / V <下取整> = Bi(注意:要二分的量不能放在等式右边)
按照常规的做题顺序,基本上是:
1.先决定要二分的量(通常是题目中要求求解的结果),并考虑二分成的两部分区间有什么含义。
2.找出二分的判断条件,即怎么才能将要二分的量二分成两个部分。
3.但有的时候,题目会很简单,简单到你把各个变量之间的关系公式列出来就能发现该题目是可以二分的,比如1227.分巧克力,4956.冶炼金属。
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e4 + 10;
int n;
int a[N], b[N];
int b_search1(int l, int r, int i)
{
while(l < r)
{
int mid = l + r >> 1;
if(a[i] / mid > b[i])
l = mid + 1;
else if(a[i] / mid <= b[i])
r = mid;
}
return l;
}
int b_search2(int l, int r, int i)
{
while(l < r)
{
int mid = l + r + 1 >> 1;
if(a[i] / mid >= b[i])
l = mid;
else if(a[i] / mid < b[i])
r = mid - 1;
}
return l;
}
int main()
{
cin >> n;
int l = 1, r0 = 0;
for(int i = 0; i < n; i ++)
{
scanf("%d%d", &a[i], &b[i]);
r0 = max(a[i], r0);
}
int r1 = r0;
//cout << r << endl;
int minl = 1, maxl = r0;
for(int i = 0; i < n; i ++)
minl = max(minl, b_search1(l, r0, i));
l = 1;
for(int i = 0; i < n; i ++)
maxl = min(maxl, b_search2(l, r0, i));
cout << minl << " " << maxl << endl;
return 0;
}
如果大家还想多了解一些较为简单的二分题目,有以下题解推荐:
https://www.acwing.com/solution/content/232016/
https://www.acwing.com/solution/content/231954/