给定一个整数N
,如何有效地找到以下范围内被7整除的数(它们的倒数也应被7整除):
[0, 10^N - 1]
示例:
对于N=2
,请回答:
4 {0, 7, 70, 77}
[从0到99的所有数字都可以被7整除(也可以将它们的反数整除)]
我的方法,简单的蛮力:
i=0
到结束运行循环a(i) % 7 == 0 && reverse(a(i)) % 7 == 0
,那么我们增加计数注意:
reverse(123) = 321
,reverse(1200) = 21
!答案 0 :(得分:3)
让我们看看将数字d
添加到前缀abc
时mod 7会发生什么。
10 * abc + d =>
(10 mod 7 * abc mod 7) mod 7 + d mod 7
reversed number:
abc + d * 10^(length(prefix) =>
abc mod 7 + (d mod 7 * 10^3 mod 7) mod 7
请注意,对于每个这样的余数,我们只需要abc mod 7
的前缀数,而不是实际的前缀。
答案 1 :(得分:3)
让 COUNTS(n,f,r)为n位数字的数量,以使 n%7 = f 和 REVERSE(n)% 7 = r
很容易计算 n = 1 的计数:
COUNTS(1,f,r)= 0 (当 f!= r 时),因为1位数与它的倒数相同。
COUNTS(1,x,x)= 1 ,当 x> = 3 ,并且
当 x <3 时,COUNTS(1,x,x)= 2 ,因为7%3 = 0、8%3 = 1和9%3 = 2
其他长度的计数可以通过计算将0到9的每个数字加到以前计数所表示的数字上时会发生的情况来得出。
最后, COUNTS(N,0,0)是您要寻找的答案。
例如,在python中,它看起来像这样:
def getModCounts(len):
counts=[[0]*7 for i in range(0,7)]
if len<1:
return counts
if len<2:
counts[0][0] = counts[1][1] = counts[2][2] = 2
counts[3][3] = counts[4][4] = counts[5][5] = counts[6][6] = 1
return counts
prevCounts = getModCounts(len-1)
for f in range(0,7):
for r in range(0,7):
c = prevCounts[f][r]
rplace=(10**(len-1))%7
for newdigit in range(0,10):
newf=(f*10 + newdigit)%7
newr=(r + newdigit*rplace)%7
counts[newf][newr]+=c
return counts
def numFwdAndRevDivisible(len):
return getModCounts(len)[0][0]
#TEST
for i in range(0,20):
print("{0} -> {1}".format(i, numFwdAndRevDivisible(i)))
查看它是否提供您期望的答案。如果没有,也许我需要修复一个错误:
0 -> 0
1 -> 2
2 -> 4
3 -> 22
4 -> 206
5 -> 2113
6 -> 20728
7 -> 205438
8 -> 2043640
9 -> 20411101
10 -> 204084732
11 -> 2040990205
12 -> 20408959192
13 -> 204085028987
14 -> 2040823461232
15 -> 20408170697950
16 -> 204081640379568
17 -> 2040816769367351
18 -> 20408165293673530
19 -> 204081641308734748
当计数到N是合理的时候,这是一个很好的答案- way 比蛮力强,计数高达10 ^ N。
对于很长的长度(例如N = 10 ^ 18)(可能会要求您输入count mod 1000000007之类的东西),会有一个下一层的答案。
请注意,长度 n 的计数与长度 n + 1 的计数之间存在线性关系,并且该关系可以由49x49矩阵表示。您可以通过对O(log N)矩阵乘法求平方,然后使用幂运算将矩阵求幂到第 N 次,然后乘以一位数即可得到长度N个计数。
答案 2 :(得分:1)
对于任何数字,都有使用数字dp技术的递归解决方案。
long long call(int pos , int Mod ,int revMod){
if(pos == len ){
if(!Mod && !revMod)return 1;
return 0;
}
if(dp[pos][Mod][revMod] != -1 )return dp[pos][Mod][revMod] ;
long long res =0;
for(int i= 0; i<= 9; i++ ){
int revValue =(base[pos]*i + revMod)%7;
int curValue = (Mod*10 + i)%7;
res += call(pos+1, curValue,revValue) ;
}
return dp[pos][Mod][revMod] = res ;
}