完美整数问题题解 | 豆包MarsCode AI刷题

148 阅读3分钟

问题描述

一个整数如果由相同的数字构成,则称为完美整数。例如:

  • 1、11、333 是完美整数。
  • 12、19、101 是不完美整数。

现在,我们需要计算给定区间 [x, y] 中有多少个整数是完美整数。

思路解析

要解决这个问题,我们可以将问题分解为以下几个步骤:

  1. 定义完美整数:一个完美整数是由相同的数字构成的整数,例如 1、11、333 等。
  2. 计算区间内的完美整数:我们需要计算在区间 [x, y] 内的所有完美整数。 为了构建 get(v) 函数,我们需要详细分析和实现以下关键步骤:

步骤分解

  1. 确定数字组成方式:首先需要一个方法来判断一个整数是否由相同的数字构成。
  2. 实现 get(v) :该函数将计算并返回所有小于等于 v 的完美整数的数量。
  3. 计算区间 [x, y] 内完美整数的数量:通过计算 get(y) - get(x-1) 来确定。

实现思路

构建 get(v)

get(v) 函数需要统计从 1 到 v 的所有整数中完美整数的数量。一种方法是遍历每个数检查,但这可能会在较大的数值范围内效率较低。 为了提高效率,可以观察到完美整数的结构:它们由重复的单个数字组成,例如 1, 11, 111, 1111, 等等。我们可以利用这一点生成这些数,而不是检查每一个数字。 对于每个基本数字(1-9),我们可以生成形如 111...1 的数,直到这个数大于 v。每个这样的数都是完美的,并且易于生成:从 d 开始(d 代表数字 1 到 9),每次将前一个数乘以 10 并加上 d

区间计数

最后,通过比较 get(y)get(x-1) 我们可以得到区间 [x, y] 中的完美整数数量。这种方式将极大地减少不必要的计算,特别是对于较大的区间。

代码详解

def solution(x, y):
    # 计算小于等于 v 的完美整数的数量
    def get(v):
        t = [int(i) for i in str(v)]
        ans = (len(t)-1)*9
        for i in range(1,10):
            c = 0
            for j in range(len(t)):
                c = c*10 + i
            if c <= v:
                ans += 1
            else:
                break
        return ans

    return get(y) - get(x-1)

if __name__ == "__main__":
    # 测试用例
    print(solution(1, 10) == 9)
    print(solution(2, 22) == 10)
    print(solution(211406, 664550) == 4)

代码解析

  1. get(v) 函数

    • 输入:一个整数 v
    • 输出:小于等于 v 的完美整数的数量。
    • 步骤
      1. v 转换为字符串并拆分为单个数字,存储在列表 t 中。
      2. 计算长度为 len(t)-1 的所有完美整数的数量。每个长度为 len(t)-1 的完美整数有 9 种可能(111, 222, ..., 999)。
      3. 对于每个数字 i(从 1 到 9),生成一个由 i 构成的长度为 len(t) 的整数 c
      4. 如果 c 小于等于 v,则增加计数。
      5. 返回计数结果。
  2. solution(x, y) 函数

    • 输入:两个整数 xy,表示区间 [x, y]
    • 输出:区间 [x, y] 内的完美整数数量。
    • 步骤
      1. 调用 get(y) 计算小于等于 y 的完美整数数量。
      2. 调用 get(x-1) 计算小于 x 的完美整数数量。
      3. 返回两者的差值,即区间 [x, y] 内的完美整数数量。