lc1015-可被K整除的最小整数

题目描述

  • 给定正整数 k,找出最小的一个数字,满足
    • 仅由 1 组成
    • 可以被 k 整除
  • 找到,返回数字长度;找不到返回 -1

示例

输入:k = 1
输出:1
解释:数字是 1,其长度为 1
输入:k = 2
输出:-1
输入:k = 3
输出:3
解释:数字是 111,其长度为 3

题解

  • 思路

模拟

  • O(n)
func smallestRepunitDivByK(k int) int {
    if k % 2 == 0 || k % 5 == 0 { return -1 }

    for i, x := 1, 1 % k; ; i ++ {
        if x == 0 { return i }
        x = (x * 10 + 1) % k
    }
}

欧拉定理

\(O(\sqrt{n} \times \log_{2}{n})\)

\[\begin{aligned} 111...1 &= \frac{10^x - 1}{9} \\ k &\mid \frac{10^x - 1}{9} \\ 9k &\mid 10^x - 1 \\ 10^x &\equiv 1 \pmod{9k} \end{aligned} \]

  • => 10 与 9k 互质
  • => 10 与 k 互质
  • => k 不能有因子 2, 5

\[\begin{aligned} 欧拉定理:\\ a^{\phi(n)} &\equiv 1 \pmod{n} \\ \Rightarrow x &= \phi(9k) \end{aligned} \]

func smallestRepunitDivByK(k int) int {
    if k % 2 == 0 || k % 5 == 0 { return -1 }

    phi := get_euler(9 * k)
    res := phi
    for i := 1; i * i <= phi; i ++ {
        if phi % i == 0 {
            if qmi(10, i, 9 * k) == 1 { return i }
            if qmi(10, phi / i, 9 * k) == 1 { res = min(res, phi / i) }
        }
    }
    return res
}

func get_euler(x int) int {
    res := x
    for i := 2; i * i <= x; i ++ {
        if x % i == 0 {
            res = res / i * (i - 1)
            for x % i == 0 { x /= i }
        }
    }
    if x > 1 { res = res / x * (x - 1) }
    return res
}

func qmi(a, b, p int) int {
    res := 1
    for b > 0 {
        if b & 1 == 1 { res = res * a % p }
        a = a * a % p
        b >>= 1
    }
    return res
}
posted @ 2025-09-02 23:21  余越  阅读(19)  评论(0)    收藏  举报