幸运数字八 - Hackerrank-W28

时间:2017-01-17 19:49:12

标签: python algorithm puzzle

给定一个n位正整数,计算并打印通过连接给定数字的数字形成的子序列数,这些数字可被8整除。由于结果可能很大,打印结果模数(10 ** 9 + 7)。 问题可以阅读here

看起来很简单,我试图解决它。我的方法,试图跟踪所有可被8整除的3位数,2位数和1位数字,因为任何被8整除的最后3位数字都可以被8整除,我厌倦了保留3位数的树并跟踪事件(2 ** p,p =前面的字符数给出序列数),但这不对,因为我无法处理数字交错的一些情况(例如9868)。

比赛结束后,我一直在寻找优雅的解决方案,因为编辑不够清楚。我遇到了一个,但无法理解发生了什么。有人可以解释以下解决方案背后的数学吗?

.controller('ListBottomSheetCtrl', function($scope) {
    $scope.data = [{
        title: 'Home',
        icon: 'home',
        link: '/page1/'
    }, {
        title: 'Email us',
        icon: 'envelope',
        link: '/page2/'
    }, {
        title: 'Profile',
        icon: 'user',
        link: '/page3/'
    }, {
        title: 'Print',
        icon: 'print',
        link: '/page4/'
    }, ];

})

ideone link

1 个答案:

答案 0 :(得分:2)

该算法背后的想法是逐步处理给定数字的前缀和每个前缀以及从r0的每个7的前缀,以计算该前缀的子序列的数量。形成一个等于r modulo 8的数字。

[n₀n₁...nₓ]为输入数字。

S(i, r)为前缀[n₀n₁...nᵢ]的子序列数,形成一个等于r模数8的数字。

为了计算S(i+1, r)的{​​{1}},我们只需知道0 ≤ r ≤ 7 S(i, r)。这就是在线性时间内逐个处理数字的原因。

0 ≤ r ≤ 7有三种子序列:

  1. 不包含[n₀n₁...nᵢ₊₁]的子序列。
    • 对于nᵢ₊₁的每个子序列[a...b][n₀n₁...nᵢ]都有一个相等的子序列。
    • 我们将[n₀n₁...nᵢ₊₁]S(i, r) S(i+1, r)添加到r,将0添加到7
  2. 包含nᵢ₊₁且前面至少有一位数的子序列。
    • 对于等于[a...b][n₀n₁...nᵢ] r 8的每个子序列[a...bnᵢ₊₁][n₀n₁...nᵢ₊₁]的{​​{1}}的子序列相等到(r*10+nᵢ₊₁)%88(从[a...bnᵢ₊₁] = 10*[a...b] + nᵢ₊₁开始)。
    • 我们将S(i, r)S(i+1, (r*10+nᵢ₊₁)%8) r添加到0,将7添加到[nᵢ₊₁]
  3. 一位数的子序列1
    • 我们将S(i+1, nᵢ₊₁ % 8)添加到S(i, 0), ..., S(i, 7)
    • 时将其考虑在内
  4. 在您引用的代码中:

    • modsS(i+1, 0), ..., S(i+1, 7) - 前一个前缀的8个数字的数组。
    • new_modsnᵢ₊₁ - 当前前缀的8个数字的数组。
    • kif(array[i]==' ') continue; - 当前前缀的最后一位数。