![](/img/trans.png)
[英]Is there an elegant way to convert a Map<P, Optional<Q>> to a sparse Map<P, Q>?
[英]Optimised way to find all integers p and q such that 2^p*3^q has a given decimal length
找出
a
和b
所有可能組合,使得r
的十進制位數是給定的數字N
。
2^p * 3^q = 10^x 對於某些 x
10^(log10(2)*p) * 10^(log10(3)*q) = 10^x
所以
x = log10(2)*p + log10(3)*q
並且您知道 x 必須介於 N - 1(包括)和 N(不包括)之間
所以你必須找到所有的 p, q :
N - 1 <= log10(2)*p + log10(3)*q < N
然后你需要找到 p 和 q 可能的最小值和最大值,如果你分析和過濾不適當的值,你可以使用循環遍歷所有 p、q 或更貪婪的解決方案
這個問題自然地推廣到找到所有p, q
的問題,使得2^p * 3^q
介於minimum
和maximum
。 其中min = 10^N
和max = 10^(N+1) - 1
。
我會講算法,也會講長度為2的特殊情況作為例子。
第一步是生成一個 2 的冪數組,直到通過max
。 換句話說, [1, 2, 4, 8, 16, 32, 64, 128]
。 任何時候你看到形式為2^p
東西都可以通過數組查找來計算。
接下來我們找到min_p
和max_p
使得對於min_p <= p <= max_p
我們有min <= 2^p <= max
。 我們通過從數組的末尾向后搜索直到找到max_p
然后向后更多地向后搜索max_p
來min_p
。 在我們的例子中, min_p = 4
和max_p = 6
。
現在我們從q=0
開始,然后進行如下操作。
q = 0
pow = 1
while 0 <= max_p:
for p between min_p and max_p:
add (p, q) to the answer
pow *= 3
q += 1
# We want min_p to stop at 0
while 0 < min_p and min < pow * 2^(min_p - 1):
min_p -= 1
# max_p going below 0 is how we know to stop.
while 0 <= max_p and max < pow * 2^max_p:
max_p -= 1
在我們的示例中,這將按如下方式工作:
min_p = 4, max_p = 6
q = 0
add (4, 0), (5, 0), (6, 0) to answer
q = 1
min_p = 2
max_p = 5
add (2, 1), (3, 1), (4, 1), (5, 1) to answer
q = 2
min_p = 0
max_p = 3
add (0, 2), (1, 2), (2, 2), (3, 2) to answer
q = 3
min_p = 0
max_p = 1
add (0, 3), (1, 3) to answer
q = 4
min_p = 0
max_p = 0
add (0, 4) to answer
q = 5
min_p = 0
max_p = -1
finish
我們現在的回答是:
(4, 0), (5, 0), (6, 0), (2, 1), (3, 1), (4, 1), (5, 1),
(0, 2), (1, 2), (2, 2), (3, 2), (0, 3), (1, 3), (0, 4)
也就是說:
16, 32, 64, 12, 24, 48, 96, 18, 36, 72, 27, 54, 81
log(N)/log(3) 算法還不夠嗎?
先求N,十進制的位數。
int count_p = 0
while (N%2 == 0) {
count_p += 1;
N /= 2;
}
int count_q = 0
while (N%3 == 0) {
count_q += 1;
N /= 3;
}
這給你 p 和 q。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.