微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

最后一个数字

如何解决最后一个数字

我正在Codewar中解决Last digit of a huge number

我设法找到一种计算odd number ^ odd numberodd number ^ even number方法。但是,由于数字与其幂的mod之间的关系不明显,所以我陷入了even ^ even/odd中。

这就是我设法得到的:

lastDigit :: [Integer] -> Integer
lastDigit = (`rem` 10) . go
  where
    go [] = 1
    go [x] = x
    go (x : y : r)
      | odd x && odd y = x ^ (go (y : r) `rem` (x + 1))
      | odd x && even y = x ^ (foldMod y (go r) (x + 1))
      | otherwise = -- any hint?

foldMod :: Integer -> Integer -> Integer -> Integer
foldMod _ 0 _ = 1
foldMod base 1 modulo = base `rem` modulo
foldMod base power modulo = (base * foldMod base (power -1) modulo) `rem` modulo

任何人都可以对偶数情况给出一些提示吗?

解决方法

我建议重新考虑您的方法,并从更通用的功能开始。具体来说,您可以计算

powMod :: Integer -> [Integer] -> Integer

powMod base exponents在哪里计算问题mod base中描述的指数塔?请注意,在递归时,您将使用不同的base进行递归-因为各个第一指数的循环长度不一定是base的所有约数。例如,在以10为底的数字中,最后四个数字为7个周期的第一个指数(而不是每十个)出现一次。权力的最后一位像这样:

x               0 1 2 3 4 5 6 7
7^x `mod` 10    1 7 9 3 1 7 9 3

您还需要注意以下情况:在到达的最终周期中,第一个指数本身不是其本身;例如,在基数4中,我们有:

x              0 1 2 3 4 5 6 7
2^x `mod` 4    1 2 0 0 0 0 0 0

因此,即使循环长度为x `mod` 1,也无法查看 just 2^x `mod` 4并推断出1是什么。 (还有其他示例,例如2^x `mod` 12,其中循环长于1,但其中仍然没有原始的2。)

,

您不需要计算整数就可以知道最后一位,有一些快速方法和不太快的方法都可以计算最后一位,而不必担心其他所有数字。

一种可以在 O(log b)时间中计算 a b 的简单方法是利用以下等式:>

(a×b)mod m =((a mod m)×(b mod m))mod m

这意味着我们每次都可以计算最后一位数字并进行处理。因此,这意味着只要我们可以表示最大为81的所有数字,就可以计算 a b mod m powMod m a b

powMod :: Int -> Int -> Int -> Int
powMod m = go
    where go _ 0 = 1
          go a b | even n = r
                 | otherwise = (x * r) `mod` m
              where r = go ((a*a) `mod` m) (div b 2) `mod` m

如果我们假设我们可以计算模数,除以2,并在恒定时间内检查值是否为偶数,等等,则在 O(log b)中运行。

但是我们甚至可以通过查找周期来更快地做到这一点。假设我们必须计算7的幂,那么7 ^ 0是1,7 ^ 1是7,7 ^ 2 mod 10 = 9,依此类推。我们可以制作一个带有乘法的表:

× │  0 1 2 3 4 5 6 7 8 9
──┼─────────────────────
0 │  0 0 0 0 0 0 0 0 0 0
1 │    1 2 3 4 5 6 7 8 9
2 │      4 6 8 0 2 4 8 6
3 │        9 2 5 8 1 4 7
4 │          6 0 4 8 2 6
5 │            5 0 5 0 5
6 │              6 2 8 4
7 │                9 6 3
8 |                  4 2
9 |                    1

因此,如果我们以7的幂为单位查看最后一位,我们将看到:

power  │     │  last digit
──────────────────────────
 0     │     │           1
 1     │ 7*1 │           7
 2     │ 7*7 │           9
 3     │ 7*9 │           3
 4     │ 7*3 │           1

因此,这意味着存在一个循环,实际上是在每次乘以7之后,我们移至下一个状态,并因此获得以下图形:

1  →  7  →  9  →  3
 ↖_______________/

因此,这意味着循环的长度为四。因此,这意味着如果我们必须将7乘以例如374的幂,那么我们知道这是93个长度为4的循环,因此没有影响,还有两个额外的移动,因此我们知道 7 393 为9,无需计算此数字。由于此类循环的最大长度为10,因此可以在固定时间内确定十进制数字的最后一位。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。