【问题标题】:Number of N-digit numbers that are divisible by given two numbers能被给定两个数整除的 N 位数
【发布时间】:2020-08-29 12:08:36
【问题描述】:

我的一个朋友在 google 编码竞赛 中遇到了这个问题。问题来了。

找出能被 X 和 Y 整除的 N 位数。 由于答案可能非常大,因此以 10^9 + 7 为模打印答案。

注意: 0 不被视为一位数。

输入: N、X、Y。

约束:

  • 1
  • 1

Eg-1 :
N = 2, X = 5, Y = 7
输出:2(35和70是必需的数字)

Eg-2 :
N = 1,X = 2,Y = 3
输出:1(6 是必需的数字)

如果对 N 的约束更小,那么它会很容易(ans = 10^N / LCM(X,Y) - 10^(N-1) / LCM(X,Y))。

但是 N 高达 1000,因此我无法解决它。

【问题讨论】:

    标签: algorithm time-complexity largenumber


    【解决方案1】:

    这个问题看起来是为了更难,但我会按照你说的方式做:

    ans = floor((10N-1)/LCM(X,Y)) - floor((10N-1-1)/LCM(X ,Y))

    诀窍是快速计算条款。

    令 M = LCM(X,Y),假设我们有:

    10a = Mqa + ra,和

    10b = Mqb + rb

    我们可以很容易地计算出来:

    10a+b = M(Mqaqb + raqb + rbqa + floor(rarb/M)) + ( rarb%M)

    使用该公式,我们可以通过平方取幂在 2 log N 步中计算 10N/M 的商和余数:https://en.wikipedia.org/wiki/Exponentiation_by_squaring

    【讨论】:

    • 但是c++不能存储这么大的数字。该值可以达到 10^10000。这是不可能存储在 c++ 变量中的
    • 所有计算商的数学都可以通过 mod 10^9 + 7 来完成,得到你的最终答案 mod 10^9 + 7
    【解决方案2】:

    以下python适用于这个问题,

    import math
    MOD  = 1000000007
    
    def sub(x,y):
        return (x-y+MOD)%MOD
    
    def mul(x,y):
        return (x*y)%MOD
    
    
    def power(x,y):
        res = 1
        x%=MOD
        while y!=0:
            if y&1 :
                res = mul(res,x)
            y>>=1
            x = mul(x,x)
            
        return res
            
    def mod_inv(n):
        return power(n,MOD-2)
    
    x,y = [int(i) for i in input().split()]
    
    m = math.lcm(x,y)
    n = int(input())
    a = -1
    b = -1
    total = 1
    for i in range(n-1):
        total = (total * 10)%m
    b = total % m
    total = (total*10)%m
    a = total % m
    
    l = power(10 , n-1)
    r = power(10 , n)
    
    ans = sub( sub(r , l) , sub(a,b)   )
    ans = mul(ans , mod_inv(m))
    
    print(ans)
    
    
    

    这个问题的方法很简单,

    让, m = lcm(x,y)

    让, 10^n -1 = m*x + a

    10^(n-1) -1 = m*y + b

    现在从以上两个等式可以清楚地看出我们的答案等于 (x - y)%MOD .

    所以,

    (x-y) = ((10^n - 10^(n-1)) - (a-b)) / m

    另外,a = (10^n)%m 和 b = (10^(n-1))%m

    使用简单的模运算规则,我们可以在 O(n) 时间内轻松计算出 a 和 b。

    对于公式中执行的减法和除法,我们可以分别使用模减法和除法。

    注意:(a/b)%MOD = ( a * (mod_inverse(b, MOD)%MOD )%MOD

    【讨论】:

    • python 中有内置的 pow 函数。 pow(a,b,c) 将计算 (a^b) % c。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多