C++ 中范围 [l, r] 内的对称数字数量(对称数字 III)2025年5月23日 | 阅读 7 分钟 Strobogrammatic 数是指将数字旋转180度后看起来相同的数字,所以它们上下颠倒后看起来是一样的。例如,69、88和818是strobogrammatic的,因为即使我们将它们翻转,它们看起来仍然是一样的。 然而,如果我们取一个像123或45这样的数字并将其翻转,它看起来会不同。因此,像这样的数字不是strobogrammatic的。如果我们得到任意两个数字l和r(包括边界),我们就必须找出l和r之间(包括l和r)有多少个strobogrammatic数。为了解决这个问题,我们需要生成所有可能的strobogrammatic数,然后在验证每个数字是否是strobogrammatic后进行计数。 在解决问题之前,了解strobogrammatic数很重要。回文数(palindromes)是指正反读都相同的数字,而strobogrammatic数有特定的旋转规则。我们不是检查一个数字反转后是否相同,而是检查一个数字旋转180度后是否看起来相同。 我们的任务是高效地查找和计数strobogrammatic数,而不是逐个检查。如果我们采用暴力方法,我们就必须遍历每个数字并查看它是否是strobogrammatic。这将非常慢,尤其是当'n'的值很大时。为了优化这一点,我们可以使用递归和一些智能过滤。 大多数时候,这类问题都涉及某些约束;在这种情况下,约束涉及到处理大数。在C++中,如果一个数字太大,它将无法正确表示。因此,此问题中的输入n实际上是一个数字的字符串表示,它可以任意大。这样做是为了避免数值溢出。 理解Strobogrammatic数为了以最佳方式解决此问题,我们首先必须知道什么是strobogrammatic数。如果一个数字的每个数字都被翻转,我们得到的数字仍然是原来的顺序,那么它就是strobogrammatic数。 如果一个数字包含除0、1、8之外的任何其他数字(例如2、3、4、5或7),那么它就不能是strobogrammatic数,因为有些数字在 upside down 翻转时没有有效的数字,或者翻转后会使数字看起来不同。 例如,如果我们取23,2和3在翻转时都没有有效的数字。
需要注意的一个重要事项是,如果我们已经有了较少位数的strobogrammatic数,我们就可以创建更多位数的strobogrammatic数。我们只需要在这些较小的strobogrammatic数两边添加一对有效的数字即可。让我们说我们已经知道的较小的数字在这里被称为基本情况,它们就是个位数的strobogrammatic数,即0、1和8。现在,使用这些基本情况,我们可以形成两位数的strobogrammatic数,如11、69、88、96等。同样,使用递归方法,我们可以生成任何strobogrammatic数。 我们还需要检查生成的strobogrammatic数是否在给定的边界[l,r]之间。边界l和r是以字符串形式给出的,所以我们可以将字符串l和r转换为数字,而不是将strobogrammatic数转换为字符串,这样比较起来就容易简单了。 此外,除非数字本身是零,否则不允许数字有多余的前导零。例如,即使0是一个有效的strobogrammatic数,我们也无法有06或08。总而言之,如果数字有多于一位,我们就不应该在开头包含零。 计数递归方法在给定范围[l,r]内查找strobogrammatic数的最优方法之一是使用递归。我们不是生成所有数字然后查看哪些是正确的,而是逐位构建有效的strobogrammatic数。这样可以避免做很多得不到答案的额外工作,从而使事情更快。 为了做到这一点,我们的递归函数采用自顶向下的方法。我们一开始没有任何数字。之后,我们添加两个构成有效strobogrammatic数的数字。关键是我们知道数字应该是什么样子,因为我们知道它必须有多长(数字的位数由n给出)以及n是奇数还是偶数。 递归步骤
导致我们停止生成新分支的因素
实现方法我们可以创建一个递归函数。它将接收到目前为止的数字、其长度以及我们想要达到的长度。在每一步,我们将添加一对有效的数字并递归调用函数。如果长度是奇数,我们只能有1、0或8。
通过这种方法,我们可以有效地计数strobogrammatic数,而无需实际生成所有这些数。时间复杂度为O(5^(n/2)),因为递归的每个级别最多会扩展到五个其他级别,因为有五个有效的数字对。即使r的值很大,由于剪枝技术,该解决方案也能很好地工作。 代码实现输出 Strobogrammatic numbers in the range [50, 1000]: 69 88 96 101 111 181 609 619 689 808 818 888 906 916 986 Total count: 14 结论总之,在给定范围[l, r]内计数strobogrammatic数是一个有趣的计算挑战,它结合了数字属性、递归和字符串操作。Strobogrammatic数在旋转180度后保持不变,它们由特定的数字对构成,如(0,0)、(1,1)、(6,9)、(8,8)和(9,6)。理解这些约束有助于高效地生成有效数字,而无需检查范围内的每个数字。 递归方法利用了对称性,通过从两端向中心构建数字,从而确保只使用有效的数字对。诸如避免前导零和确保字典序比较之类的剪枝技术有助于优化性能。该算法不是通过蛮力检查每个数字,而是构建不同长度的strobogrammatic数,并验证它们在给定范围内的有效性。 总体时间复杂度为O(5^(n/2)),该解决方案对于中等大小的输入来说是高效的。该实现有效地生成和计数strobogrammatic数,同时处理诸如个位数、前导零和不同字符串长度等边缘情况。 这个问题展示了递归在生成组合方面的强大功能。它可以应用于各种领域,包括数字表示、检查对称性以及研究数字模式。学习这些有组织的数值特征可以提高解决编程算法问题的专业知识。 |
在本文中,我们将讨论其语法和示例。简介 一个强大的 C++ 工具 std::regex_replace 使程序员能够使用正则表达式查找和替换文本。它是一种搜索字符串中的模式并替换该模式实例的有用方法...
5 分钟阅读
在数字方面,斐波那契数列和佩尔数数列具有相似的递推关系。佩尔数由递推关系定义:p(n)=2*p(n-1)+p(n-2),其初始值为 p(0)=0 & p(1)=1。这些是前几个佩尔数:0、1、2、5、12、29、70、...
阅读 4 分钟
概述 “半平面交”算法是一种几何方法,用于计算二维区域内一个或多个半平面的交集。半平面是指飞机被数学几何中的直线划分成的两个方面之一,直线 appears as...
11 分钟阅读
?C++23,这是最新的 C++ 标准,如今已在很大程度上被采用。它动态且丰富,拥有许多新功能,可以帮助我们改进语言的词汇和语篇。本文将描述每项新功能,这些功能将……
阅读 4 分钟
Alexander Bogomolny 的无序排列算法生成前 'n' 个自然数。此方法将以字典顺序生成所有排列,这意味着所有生成的排列都按非降序排列。当 'n' 值非常大或输入...时使用此方法。
5 分钟阅读
这是 <random> 库的一部分,用于模拟 Student's t 分布。在假设检验中经常使用它,因为样本数量通常较小,并且总体方差未知。t 分布,通常称为 Student's t 分布,是……
阅读 4 分钟
在本文中,我们将讨论如何在 C++ 中查找两个 multimaps 的对称差。在进行实现之前,我们必须了解 multimaps。C++ 中的 Multimap 是什么?在 C++ 中,“std::multimap”是一个关联容器,它存储键值对,其中...
阅读 6 分钟
计算机科学领域的主要挑战之一是计算系统内任务的交互。由于系统的复杂性不断增加,因此必须拥有技术先进的调度算法。在这些算法中,优先级调度算法很清楚...
阅读 19 分钟
在本文中,我们将讨论如何在 C++ 中找到引爆所有气球所需的最少箭数。问题陈述:给定一个大小为 N 的数组,其中 points[i] 表示覆盖 X 坐标中 points[i][0] 和 points[i][1] 区域的气球....
阅读 4 分钟
在本文中,我们讨论。分段筛是一种普通筛算法的优化版本。与计算所有数的倍数的普通筛不同,分段筛只计算某些素数的倍数...
阅读 6 分钟
我们请求您订阅我们的新闻通讯以获取最新更新。
我们提供所有技术(如 Java 教程、Android、Java 框架)的教程和面试问题
G-13, 2nd Floor, Sec-3, Noida, UP, 201301, India