给定一个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/'
}, ];
})
答案 0 :(得分:2)
该算法背后的想法是逐步处理给定数字的前缀和每个前缀以及从r
到0
的每个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
有三种子序列:
[n₀n₁...nᵢ₊₁]
的子序列。
nᵢ₊₁
的每个子序列[a...b]
,[n₀n₁...nᵢ]
都有一个相等的子序列。 [n₀n₁...nᵢ₊₁]
从S(i, r)
S(i+1, r)
添加到r
,将0
添加到7
。nᵢ₊₁
且前面至少有一位数的子序列。
[a...b]
模[n₀n₁...nᵢ]
r
8
的每个子序列[a...bnᵢ₊₁]
,[n₀n₁...nᵢ₊₁]
的{{1}}的子序列相等到(r*10+nᵢ₊₁)%8
模8
(从[a...bnᵢ₊₁] = 10*[a...b] + nᵢ₊₁
开始)。 S(i, r)
从S(i+1, (r*10+nᵢ₊₁)%8)
r
添加到0
,将7
添加到[nᵢ₊₁]
。1
。
S(i+1, nᵢ₊₁ % 8)
添加到S(i, 0), ..., S(i, 7)
。在您引用的代码中:
mods
是S(i+1, 0), ..., S(i+1, 7)
- 前一个前缀的8个数字的数组。new_mods
是nᵢ₊₁
- 当前前缀的8个数字的数组。k
是if(array[i]==' ') continue;
- 当前前缀的最后一位数。