二分通常指的是二分查找(Binary Search),它是一种高效的查找算法,用于在有序数组中查找某一特定元素的位置。二分查找的思路是:
给定一个按照升序排列的长度为 n 的整数数组,以及 q 个查询。
对于每个查询,返回一个元素 k 的起始位置和终止位置(位置从 0 开始计数)。
如果数组中不存在该元素,则返回 -1 -1
。
#include
using namespace std;
const int N = 1e5 + 5;
int arr[N];
int n, q;
int main()
{
int k = 0;
scanf("%d%d", &n, &q);
for (int i = 0; i < n; i++) scanf("%d", &arr[i]);
while (q--)//循环q次
{
scanf("%d", &k);//查询的数
int l = 0, r = n - 1;//首尾
while (l < r)//l=r时停止
{
int mid = l + r >> 1;//中点
if (arr[mid] >= k) r = mid;//中值>=k,缩小范围0到mid
else l = mid + 1;//中值<=k,缩小范围mid+1到n-1
}//以此类推求出左边界
if (arr[l] != k)//如果剩下的一个不是k返回-1 -1
{
printf("-1 -1\n");
continue;//结束本次循环
}
else printf("%d ", l);//是k,输出序号
r = n - 1;
while (l < r)
{
int mid = l + r + 1 >> 1;//加1向上取整,求左边界向下,求右边界向上对称
if (arr[mid] <= k) l = mid;//对称
else r = mid - 1;//对称
}
printf("%d\n", l);//输出右边界
}
return 0;
}
while (l < r)//l=r时停止
{
int mid = l + r >> 1;//中点
if (arr[mid] >= k) r = mid;//中值>=k,缩小范围0到mid
else l = mid + 1;//中值<=k,缩小范围mid+1到n-1
}//以此类推求出左边界
1.查找左边界,中点值与查找值比较然后缩小范围,中间值大右边界缩小到 mid,中间值左边界缩小到mid + 1,循环直到 l = r,
if (arr[l] != k)//如果剩下的一个不是k返回-1 -1
{
printf("-1 -1\n");
continue;//结束本次循环
}
else printf("%d ", l);//是k,输出序号
2.判断结束时对应的数是不是要查找的数,不是的话输出 -1 停止本次循环,是的话输出左边界 l
r = n - 1;
while (l < r)
{
int mid = l + r + 1 >> 1;//加1向上取整,求左边界向下,求右边界向上对称
if (arr[mid] <= k) l = mid;//对称
else r = mid - 1;//对称
}
3.求右边界,更新 r,求左边界到末尾的右边界,求法与左边界类似,对称, l + r + 1 >> 1 向上取整,因为下一步 if 判断条件是 <=,到最后一步剩两个元素的时候向下取整会发生死循环,即
l+1=r
l
给定一个浮点数 n,求它的三次方根。(-10000 n 的范围 循环条件 l 与 r 的差值大于10的-8次方,为所求值的精度,通过中点值的3次方与所开值比较所小范围,直到循环结束得到所求值 根据迭代公式 求解 迭代求解即可 设定两个变量分别储存迭代前和迭代后的结果,其中x可为任意正整数 循环条件:迭代后的值-迭代前的值>10的-8次方代码
1.二分法
#include
2.牛顿迭代法
#include
解析
1.二分法
double l = -10000, r = 10000;
while (r - l > 1e-8) //精度
{
double mid = (l + r) / 2;//取中点
if (mid * mid * mid >= x) r = mid;//mid在右,替换r
else l = mid;
}
2.牛顿迭代法
的根
double x = n, prev_t = x - 1;
while (abs(x - prev_t) > 1e-8)//精度
{
prev_t = x;
x = (2 * x * x * x + n) / (3 * x * x);//牛顿迭代
}