C++二分查找算法的应用:第 N 个神奇数字

简介: C++二分查找算法的应用:第 N 个神奇数字

本文涉及的基础知识点

二分查找算法合集

题目

一个正整数如果能被 a 或 b 整除,那么它是神奇的。

给定三个整数 n , a , b ,返回第 n 个神奇的数字。因为答案可能很大,所以返回答案 对 109 + 7 取模 后的值。

示例 1:

输入:n = 1, a = 2, b = 3

输出:2

示例 2:

输入:n = 4, a = 2, b = 3

输出:6

提示:

1 <= n <= 109

2 <= a, b <= 4 * 104

分析

令f(x)等于[1,x]神奇数字的数量,寻找第一个f(x)大于等于n的x,用左开右闭的二分查找。结果一定在[1,max(a,b)*n]中。

神奇数字数量

神奇数字数量等于= 被a整除+ 被b整除 - 同时被a和b整除

同时被a和b整除:被a和b的最小公倍数整除,不是被a*b整除

代码

核心代码

int GCD(int n1, int n2)
{
int t1 = min(n1, n2);
int t2 = max(n1, n2);
if (0 == t1)
{
return t2;
}
return GCD(t2 % t1, t1);
}
class Solution {
public:
int nthMagicalNumber(int n, int a, int b) {
long long left = -1, right = max(a, b) * (long long)n ;
while (right - left > 1)
{
const auto mid = left + (right - left) / 2;
const long long llNum = mid / a + mid / b - mid /( a * b/GCD(a,b));
if( llNum >= n )
{
right = mid;
}
else
{
left = mid;
}
}
return right%(100010001000+7);
}
};

测试用例

template
void Assert(const T& t1, const T& t2)
{
assert(t1 == t2);
}
template
void Assert(const vector& v1, const vector& v2)
{
if (v1.size() != v2.size())
{
assert(false);
return;
}
for (int i = 0; i < v1.size(); i++)
{
Assert(v1[i], v2[i]);
}
}
int main()
{
vector<vector> grid;
int res = 0;
{
Solution slu;
res = slu.nthMagicalNumber(5, 2, 4);
Assert(10, res);
}
{
Solution slu;
res = slu.nthMagicalNumber(3, 4, 1000);
Assert(12, res);
}
{
Solution slu;
res = slu.nthMagicalNumber(4, 2, 3);
Assert(6, res);
}
//CConsole::Out(res);

}

左闭右开也可以,就是复杂些。

一,先找到最后一个f(x)<=n的x。

二,max(x-x%a,x-x%b);

比如: n =3 a =2 b =3 f(5)是最后一个等于3的x,结果是4。

class Solution {
public:
int nthMagicalNumber(int n, int a, int b) {
long long left = 0, right = max(a, b) * (long long)n+1 ;
while (right - left > 1)
{
const auto mid = left + (right - left) / 2;
const long long llNum = mid / a + mid / b - mid /( a * b/GCD(a,b));
if( llNum <= n )
{
left = mid;
}
else
{
right = mid;
}
}
left = max(left - left % a, left - left % b);
return left %(100010001000+7);
}
};

2023年3月旧代码

class Solution {
public:
int nthMagicalNumber(int n, int a, int b) {
const int iComMul = ab/GCD(a, b);
long long left = -1, right = max(a, b)(long long)n;
while (right > left + 1)
{
auto llMid = left + (right - left) / 2;
long long llNum = llMid / a + llMid / b - llMid / iComMul;
if (llNum >= n)
{
right = llMid;
}
else
{
left = llMid;
}
}
return right % (1000 * 1000 * 1000 + 7);
}
};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。

https://edu.csdn.net/course/detail/38771

如何你想快

速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程

https://edu.csdn.net/lecturer/6176

相关下载

想高屋建瓴的学习算法,请下载《闻缺陷则喜算法册》doc版

https://download.csdn.net/download/he_zhidan/88348653

洒家想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
墨家名称的来源:有所得以墨记之。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17

或者 操作系统:win10 开发环境:

VS2022 C++17


相关文章
|
21天前
|
存储 算法 Java
解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用
在Java中,Set接口以其独特的“无重复”特性脱颖而出。本文通过解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用。
38 3
|
27天前
|
机器学习/深度学习 人工智能 自然语言处理
深度学习中的优化算法及其应用
【10月更文挑战第8天】 本文将探讨深度学习中常用的优化算法,包括梯度下降法、Adam和RMSProp等,介绍这些算法的基本原理与应用场景。通过实例分析,帮助读者更好地理解和应用这些优化算法,提高深度学习模型的训练效率与性能。
125 63
|
4天前
|
机器学习/深度学习 JSON 算法
二叉树遍历算法的应用场景有哪些?
【10月更文挑战第29天】二叉树遍历算法作为一种基础而重要的算法,在许多领域都有着不可或缺的应用,它为解决各种复杂的问题提供了有效的手段和思路。随着计算机科学的不断发展,二叉树遍历算法也在不断地被优化和扩展,以适应新的应用场景和需求。
10 0
|
13天前
|
存储 并行计算 安全
C++多线程应用
【10月更文挑战第29天】C++ 中的多线程应用广泛,常见场景包括并行计算、网络编程中的并发服务器和图形用户界面(GUI)应用。通过多线程可以显著提升计算速度和响应能力。示例代码展示了如何使用 `pthread` 库创建和管理线程。注意事项包括数据同步与互斥、线程间通信和线程安全的类设计,以确保程序的正确性和稳定性。
|
15天前
|
存储 算法 搜索推荐
这些算法在实际应用中有哪些具体案例呢
【10月更文挑战第19天】这些算法在实际应用中有哪些具体案例呢
23 1
|
21天前
|
机器学习/深度学习 人工智能 算法
[大语言模型-算法优化] 微调技术-LoRA算法原理及优化应用详解
[大语言模型-算法优化] 微调技术-LoRA算法原理及优化应用详解
56 0
[大语言模型-算法优化] 微调技术-LoRA算法原理及优化应用详解
|
26天前
|
算法 C# 索引
C#二分查找算法
C#二分查找算法
|
15天前
|
监控 算法 数据挖掘
HyperLogLog算法有哪些应用场景呢
【10月更文挑战第19天】HyperLogLog算法有哪些应用场景呢
12 0
|
21天前
|
机器学习/深度学习 算法 数据建模
计算机前沿技术-人工智能算法-生成对抗网络-算法原理及应用实践
计算机前沿技术-人工智能算法-生成对抗网络-算法原理及应用实践
23 0
|
26天前
|
算法 数据处理 C++
c++ STL划分算法;partition()、partition_copy()、stable_partition()、partition_point()详解
这些算法是C++ STL中处理和组织数据的强大工具,能够高效地实现复杂的数据处理逻辑。理解它们的差异和应用场景,将有助于编写更加高效和清晰的C++代码。
20 0