C++二分查找算法:阶乘函数后 K 个零

简介: C++二分查找算法:阶乘函数后 K 个零

本文涉及的基础知识点

二分查找算法合集

题目

f(x) 是 x! 末尾是 0 的数量。回想一下 x! = 1 * 2 * 3 * … * x,且 0! = 1 。

例如, f(3) = 0 ,因为 3! = 6 的末尾没有 0 ;而 f(11) = 2 ,因为 11!= 39916800 末端有 2 个 0 。

给定 k,找出返回能满足 f(x) = k 的非负整数 x 的数量。

示例 1:

输入:k = 0

输出:5

解释:0!, 1!, 2!, 3!, 和 4! 均符合 k = 0 的条件。

示例 2:

输入:k = 5

输出:0

解释:没有匹配到这样的 x!,符合 k = 5 的条件。

示例 3:

输入: k = 3

输出: 5

参数范围

0 <= k <= 109

分析

时间复杂度

O(logn*log5n)。FirstEqualMore内的循环logn次,GetNum内循环log5N。

0个数

0的个数就是2和5的个数的较小者。5的个数一定不会多余2的个数,所以计算5的个数就可以了。

如果5x<=value,那么2x一定小于value。

除非是0个,否则5的个数一定不会等于2的个数。

令x>0,则5x/2 = 2x+x/2 >2x > x

5个数

初步想法

非25的倍数,5的倍数 +1
非125的倍数,25的倍数 +2
非625的倍数,125的倍数 +3

可以这样想

5的倍数 +1
25的倍数 +1
125的倍数 +1

二分

初:寻找第一个和最后一个x,使得f(x)等于k,两者相减再+1。要特殊处理不存在f(x)等于k。所以改成寻找x1=第一个f(x)大于等于k,x2=第一个f(x)大于k,x2也是第一个f(x)大于等于k+1。

代码

核心代码

class Solution {
public:
int preimageSizeFZF(int k) {
return FirstEqualMore(k + 1) - FirstEqualMore(k);
}
int FirstEqualMore(int k)
{
long long left = -1, right = k * 5LL;
while (right - left > 1)
{
const auto mid = left + (right - left) / 2;
if (GetNum(mid) >= k)
{
right = mid;
}
else
{
left = mid;
}
}
return right;
}
long long GetNum(long long llVaue)
{
long long llRet = 0;
long long five = 5;
while (five <= llVaue)
{
llRet += llVaue / five;
five *= 5;
}
return llRet;
}
};

测试用例

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.preimageSizeFZF(0);
Assert(5, res);
}
{
Solution slu;
res = slu.preimageSizeFZF(5);
Assert(0, res);
}
{
Solution slu;
res = slu.preimageSizeFZF(3);
Assert(5, res);
}
//CConsole::Out(res);

}

2023年3月旧代码

如果f(x)等于k,则f(x+1)、f(x+2)、f(x+3)、f(x+4)都等于k。如果不存在f(x)等于k,则结果为0。所以只有两种返回值,5或0。

class Solution {
public:
int preimageSizeFZF(int k) {
int left = 0, right = 1000 * 1000 * 1000 + 1;
while (right > left + 1)
{
int iMid = left + (right - left) / 2;
const int iNum = GetFiveNum(iMid);
if (iNum == k)
{
return 5;
}
else if (iNum < k)
{
left = iMid;
}
else
{
right = iMid;
}
}
return (GetFiveNum(left) == k) ? 5 : 0;
}
//获取[0,iMax*5] 质因数5的个数
int GetFiveNum(int iMax)
{
int iNum = iMax;
int tmp = 5;
while (iMax >= tmp)
{
iNum += iMax / tmp;
tmp *= 5;
}
return iNum;
}
};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步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


相关文章
|
12月前
|
存储 监控 算法
基于 C++ 哈希表算法实现局域网监控电脑屏幕的数据加速机制研究
企业网络安全与办公管理需求日益复杂的学术语境下,局域网监控电脑屏幕作为保障信息安全、规范员工操作的重要手段,已然成为网络安全领域的关键研究对象。其作用类似网络空间中的 “电子眼”,实时捕获每台电脑屏幕上的操作动态。然而,面对海量监控数据,实现高效数据存储与快速检索,已成为提升监控系统性能的核心挑战。本文聚焦于 C++ 语言中的哈希表算法,深入探究其如何成为局域网监控电脑屏幕数据处理的 “加速引擎”,并通过详尽的代码示例,展现其强大功能与应用价值。
233 2
|
存储 算法 C++
Windows共享文件:探秘C++实现的B树索引算法奇境
在数字化时代,Windows共享文件的高效管理至关重要。B树算法以其自平衡多路搜索特性,在文件索引与存储优化中表现出色。本文探讨B树在Windows共享文件中的应用,通过C++实现具体代码,展示其构建文件索引、优化数据存储的能力,提升文件检索效率。B树通过减少磁盘I/O操作,确保查询高效,为企业和个人提供流畅的文件共享体验。
|
存储 负载均衡 算法
基于 C++ 语言的迪杰斯特拉算法在局域网计算机管理中的应用剖析
在局域网计算机管理中,迪杰斯特拉算法用于优化网络路径、分配资源和定位故障节点,确保高效稳定的网络环境。该算法通过计算最短路径,提升数据传输速率与稳定性,实现负载均衡并快速排除故障。C++代码示例展示了其在网络模拟中的应用,为企业信息化建设提供有力支持。
367 15
|
8月前
|
存储 算法 搜索推荐
软考算法破壁战:从二分查找到堆排序,九大排序核心速通指南
专攻软考高频算法,深度解析二分查找、堆排序、快速排序核心技巧,对比九大排序算法,配套动画与真题,7天掌握45%分值模块。
337 1
软考算法破壁战:从二分查找到堆排序,九大排序核心速通指南
|
运维 监控 算法
解读 C++ 助力的局域网监控电脑网络连接算法
本文探讨了使用C++语言实现局域网监控电脑中网络连接监控的算法。通过将局域网的拓扑结构建模为图(Graph)数据结构,每台电脑作为顶点,网络连接作为边,可高效管理与监控动态变化的网络连接。文章展示了基于深度优先搜索(DFS)的连通性检测算法,用于判断两节点间是否存在路径,助力故障排查与流量优化。C++的高效性能结合图算法,为保障网络秩序与信息安全提供了坚实基础,未来可进一步优化以应对无线网络等新挑战。
|
存储 算法 数据处理
公司局域网管理中的哈希表查找优化 C++ 算法探究
在数字化办公环境中,公司局域网管理至关重要。哈希表作为一种高效的数据结构,通过哈希函数将关键值(如IP地址、账号)映射到数组索引,实现快速的插入、删除与查找操作。例如,在员工登录验证和设备信息管理中,哈希表能显著提升效率,避免传统线性查找的低效问题。本文以C++为例,展示了哈希表在局域网管理中的具体应用,包括设备MAC地址与IP分配的存储与查询,并探讨了优化哈希函数和扩容策略,确保网络管理高效准确。
|
12月前
|
监控 算法 数据处理
基于 C++ 的 KD 树算法在监控局域网屏幕中的理论剖析与工程实践研究
本文探讨了KD树在局域网屏幕监控中的应用,通过C++实现其构建与查询功能,显著提升多维数据处理效率。KD树作为一种二叉空间划分结构,适用于屏幕图像特征匹配、异常画面检测及数据压缩传输优化等场景。相比传统方法,基于KD树的方案检索效率提升2-3个数量级,但高维数据退化和动态更新等问题仍需进一步研究。未来可通过融合其他数据结构、引入深度学习及开发增量式更新算法等方式优化性能。
287 17
|
存储 算法 C++
【C++数据结构——查找】二分查找(头歌实践教学平台习题)【合集】
二分查找的基本思想是:每次比较中间元素与目标元素的大小,如果中间元素等于目标元素,则查找成功;顺序表是线性表的一种存储方式,它用一组地址连续的存储单元依次存储线性表中的数据元素,使得逻辑上相邻的元素在物理存储位置上也相邻。第1次比较:查找范围R[0...10],比较元素R[5]:25。第1次比较:查找范围R[0...10],比较元素R[5]:25。第2次比较:查找范围R[0..4],比较元素R[2]:10。第3次比较:查找范围R[3...4],比较元素R[3]:15。,其中是顺序表中元素的个数。
615 68
【C++数据结构——查找】二分查找(头歌实践教学平台习题)【合集】
|
11月前
|
存储 机器学习/深度学习 算法
基于 C++ 的局域网访问控制列表(ACL)实现及局域网限制上网软件算法研究
本文探讨局域网限制上网软件中访问控制列表(ACL)的应用,分析其通过规则匹配管理网络资源访问的核心机制。基于C++实现ACL算法原型,展示其灵活性与安全性。文中强调ACL在企业与教育场景下的重要作用,并提出性能优化及结合机器学习等未来研究方向。
275 4
|
10月前
|
存储 监控 算法
基于跳表数据结构的企业局域网监控异常连接实时检测 C++ 算法研究
跳表(Skip List)是一种基于概率的数据结构,适用于企业局域网监控中海量连接记录的高效处理。其通过多层索引机制实现快速查找、插入和删除操作,时间复杂度为 $O(\log n)$,优于链表和平衡树。跳表在异常连接识别、黑名单管理和历史记录溯源等场景中表现出色,具备实现简单、支持范围查询等优势,是企业网络监控中动态数据管理的理想选择。
252 0