洛谷P2759 奇怪的函数(二分法,关于左闭右闭,左闭右开的问题没想明白的请看Carl大师,链接下面补充)

#include<stdio.h>
#include<math.h>

int findMin(int n) {//左闭右开
	int l = 1, r = 2e9;//2E9表示INT_MAX
	while (l < r) {
		int mid = (r - l) / 2 + l;//这里为了避免越界问题mid+(l+r)/2,写成我那样
		if (mid * log10(mid) +1< n) {
			l = mid + 1;
		}
		else {
			r = mid;
		}
	}
	return l;
}
int main() {
	int n;
	scanf("%d", &n);
	int result = findMin(n);
	printf("%d", result);
	return 0;
}





//左闭右闭
//int findMin(int n) {
//	int l = 1, r = 2e9-1;
//	while (l <= r) {
//		int mid = (r - l) / 2 + l;
//		if (mid * log10(mid) +1< n) {
//			l = mid + 1;
//		}
//		else {
//			r = mid-1;
//		}
//	}
//	return l;
//}

ps:

1.有些编译器可能没有math的库函数log10,所以需要用到换底公式。

2.求一个数是多少位,有一个方法如下图,log10x的x次方,把x次幂提到前面,就是x乘以log10x+1,比如100是三位数,log10(100)=2,2+1=3,所以是三位数

3.以防越界问题没懂的话请看carl的视频,链接在下面

 

5.

这道题使用二分法的原因是,我们要找到一个最小的正整数 x,使得 x^x 的位数达到或超过给定的 n。通过观察,我们知道 x 是一个递增函数,即 x 越大,x^x 的值越大。

使用二分法的关键在于,我们可以通过检查 x 的中间值来确定我们应该在哪一侧继续搜索。如果 mid * log10(mid) < n,那么说明 mid 还不够大,我们需要在 mid 的右侧搜索;否则,说明 mid 可能太大,我们需要在 mid 的左侧搜索。

这样,通过二分法,我们能够在每次迭代中缩小搜索范围,快速找到满足条件的最小正整数 x。由于 x 是递增的,因此在找到一个满足条件的 x 后,就可以确保它是最小的。

总的来说,使用二分法可以有效地加速搜索过程,减少不必要的计算,从而更高效地找到满足条件的最小正整数 x。

这是左闭右闭,r=numsize-1

这是左闭右开

链接在此:Carl很强,大家多向他学习!!!

https://www.bilibili.com/video/BV1fA4y1o715/?spm_id_from=333.337.search-card.all.click&vd_source=bd64c3d19eace74a8f4781bdb1026eb4

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
二分法查找是一种高效搜索算法,它通过将有序数组分成两半来进行查找操作。以下是基本步骤: 1. **初始化**:首先确定整个数组的范围,通常初始时左右指针分别指向数组的第一个元素(左边界)和最后一个元素(右边界)。 2. **找到中间点**:计算数组的中间索引 `mid`,可以通过 `(left + right) / 2` 来计算。为了防止整数溢出,在实际编码时推荐使用 `left + (right - left) / 2` 或者 `left + ((right - left) >> 1)` 这样的写法。 3. **比较目标值与中间值**: - 如果中间值等于目标值,则找到了目标位置并返回结果。 - 如果中间值小于目标值,则更新左边界为 `mid + 1` ,因为目标值存在于右半部分。 - 如果中间值大于目标值,则更新右边界为 `mid - 1` ,因为目标值存在于左半部分。 4. **循环条件**:只要左边界小于或等于右边界,就继续执行上述步骤;如果左边界超过了右边界,则说明查找失败,并返回未找到的结果(通常是 `-1`、`false` 等标志值表示未找到)。 下面是一个简单的 C++ 实现示例: ```cpp #include <iostream> using namespace std; int binarySearch(int arr[], int l, int r, int x) { while (l <= r) { int m = l + (r - l) / 2; // Check if x is present at mid if (arr[m] == x) return m; // If x greater, ignore left half if (arr[m] < x) l = m + 1; // If x is smaller, ignore right half else r = m - 1; } // If we reach here, then element was not present return -1; } int main() { int arr[] = {2, 3, 4, 10, 40}; int n = sizeof(arr)/sizeof(arr); int x = 10; int result = binarySearch(arr, 0, n-1, x); (result == -1) ? cout << "Element is not present in array" : cout << "Element is present at index " << result; return 0; } ``` 这个例子展示了如何在数组中查找特定元素的过程,实现了从数组两端缩小查找范围直至找到元素或确认不存在的过程。理解并掌握二分查找的基本原理对于优化算法效率非常关键。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值