[Codewars]-Last digit of a large number

大数字的最后一位数字(Last digit of a large number) ——大数取模

题目:

  • 题目很简单,给出a,b两个数字,计算 a b 的最后一位数字。
  • 例如:a=2,b=4 a b = 2 4 = 16 ,故16的最后一位数字应该是6

思路:

  • 对于小数,直接计算然后取模(%10)就可以了
  • 但是对于大数,往往就会计算不出来或者十分费时。
  • 想了很久,做了很多尝试方案,发现都是时间爆栈了。。
  • 后来百度了下才发现这个叫快速幂取模。。。可怜楼主没有ACM经验,数学数论也不行。。。
  • 那我们直接根据快速幂取模的方法计算就可以了。

讲解快速幂取模:

首先有如下公式:

a b % m = [ ( a % m ) ( b % m ) ] % m

其证明过程如下:
a = a 1 m + a 2 b = b 1 m + b 2 a b % m = a 2 b 2 % m = [ ( a % m ) ( b % m ) ] % m

因此 a b % m 有如下公式:
a b % m = [ ( a % m ) b ] % m = [ ( a % m ) ( a % m ) b 1 ] % m = { ( a % m ) [ ( a % m ) b 1 % m ] } % m

不过根据上面公式,如果b足够大的时候,计算的耗时依旧非常大。

于是可以用下面这种方法:
快速幂算法+可迅速求出 a b 。其主要的理论依据如下:
1. 当b是偶数时, a b 可以转化为 a 2 b / 2 次方。
2. 当b是奇数时, a b 可以转化为 a 2 b / 2 次方,再乘以 a

利用快速幂方法,可以迅速求出一个数的任意次方,再结合 a b % m = { ( a % m ) [ ( a % m ) b 1 % m ] } % m 公式,就可以得到下面代码:

解答:

(python 2.7)

def last_digit(a, b):
    sum = 1
    a = a%10
    while b>0 :
        if b%2 == 1:
            sum = sum * a % 10
        b /= 2
        a = a * a % 10
    return sum

后记:

一开始我坚持用js写的。后来发现3715290469715693021198967285016729344580685479654510946723这个数字,在js里会变成科学计数法:3.715290469715693e+57,而且 3715290469715693021198967285016729344580685479654510946723 % 10 = 8 ,这明显不对嘛。。。于是放弃转战python,顺利实现

提交之后看见大神的答案,发现自己还是太年轻了

def last_digit(n1, n2):
    return pow( n1, n2, 10 )

而且能够通过测试

果然python处理数据也是很强大的

参考文献:

  1. 快速幂—java_c_android
  2. 快速幂与快速取模—flqbestboy
  3. ACM算法:快速幂取模(详细)—陌梦路

猜你喜欢

转载自blog.csdn.net/qq_41882147/article/details/81029486