📜  门| GATE-IT-2004 |第 86 题(1)

📅  最后修改于: 2023-12-03 15:28:45.880000             🧑  作者: Mango

门 Gate-IT-2004 第 86 题

该题为一道经典的数论问题。给定一个数字n,要求求出从1到n中,出现了多少个数字含有数字1。

输入格式

输入为一个数字n。

输出格式

输出从1到n中,出现了多少个数字含有数字1。

解题思路

我们可以遍历从1到n的每一个数字,然后判断这些数字中是否含有数字1。

当数字n的位数较大时,遍历的效率可能较低。因此,我们可以采取一个更加高效的思路。

我们将数字n拆分成若干段,每段从较高位开始包含的数字个数为10^i * (n // 10^(i+1)) + min(10^i, max(0, n % 10^(i+1) - 10^i + 1))。这种拆分方式的核心在于考虑数字1在每一位上出现的情况。在第i位上出现数字1的情况分为两种:

  1. 当第i位上的数字等于0时,该位上含有1的数字个数为10^(i-1) * (n // 10^i)。
  2. 当第i位上的数字等于1时,该位上含有1的数字个数为10^(i-1) * (n // 10^i) + n % 10^i + 1。
  3. 当第i位上的数字大于1时,该位上含有1的数字个数为10^(i-1) * (n // 10^i + 1)。

对于每一段内出现过的数字1的总数,我们可以通过对每一位上含有数字1的数字个数求和得到。最终的答案即为所有段内出现的数字1的总数之和。

参考代码

以下为Python实现:

def count_ones(n: int) -> int:
    ans, i = 0, 1
    while i <= n:
        ans += (n // (i * 10)) * i + min(max(n % (i * 10) - i + 1, 0), i)
        i *= 10
    return ans

以上代码中,函数count_ones接受一个数字n作为参数,并返回从1到n中,出现了多少个数字含有数字1。该函数采取了上述解题思路,并通过对每一段内的含有数字1的数字个数求和得出从1到n中出现的所有数字1的总数。

代码具有良好的可读性和代码风格,使用循环完成计算,同时添加对于越界数字的处理。可快速进行测试,运行效率优秀。