简体   繁体   English

找到 2^k 以 n 开头的最小 k

[英]Finding the minimal k that 2^k begins with n

Given a positive integer n ≤ 10 7 , I need to find the least positive integer k such that the decimal representation of 2 k starts with the decimal representation of n .给定一个正整数n ≤ 10 7 ,我需要找到最小的正整数k ,使得 2 k的十进制表示以n的十进制表示开头。

So, for example, if n = 12, then k = 7 (because 2 7 = 12 8);因此,例如,如果n = 12,则k = 7(因为 2 7 = 12 8); if n = 134, then k = 27 (because 2 27 = 134 ,217,728);如果n = 134,则k = 27(因为 2 27 = 134 ,217,728); and if n = 82, then k = 209 (because 2 2098.2 3×10 62 ).如果n = 82,则k = 209(因为 2 2098.2 3×10 62 )。

(If no such k exists, I need to return −1.) (如果不存在这样的k ,我需要返回 -1。)

I didn't even attempt to solve it with the formula (I have NO idea how), and decided to solve by calculating all powers of 2 up to 1000, putting them in a list, and then finding the index of the number that begins with n.我什至没有尝试用公式来解决它(我不知道如何解决),并决定通过计算 2 到 1000 的所有幂,将它们放在一个列表中,然后找到开始的数字的索引来解决与 n. The code works, but... It doesn't even pass the first test in the system.该代码有效,但是...它甚至没有通过系统中的第一个测试。 I have no clue why, because it works correctly for the above examples.我不知道为什么,因为它适用于上述示例。 Anyway, here is the code.无论如何,这是代码。

def find_all():
    arr = []
    n = 1
    for i in range(1000):
        arr.append(str(n))
        n = n << 1
    return arr


n = str(n)
NOT_FOUND = True
#n = input()
arr = find_all()
for i in arr:
    if i.startswith(n):
        print(arr.index(i), n)
        NOT_FOUND = False
        break
if NOT_FOUND:
    print(-1, n)

What could be wrong?可能有什么问题?

Suppose you want to find a power of 2 that starts with 123.假设您要查找以 123 开头的 2 的幂。

This is equivalent to finding a multiple of log 10 (2) whose mantissa lies between 0.089905111439398 and 0.093421685162235 (because log 10 (123) = 2.089905111439398 and log 10 (124) = 2.093421685162235).这等效于寻找日志10的(2),其多重尾数谎言0.089905111439398和0.093421685162235(因为日志10(123)= 2.089905111439398和日志10(124)= 2.093421685162235)之间。

If you frame the question in this way, there's no need to calculate huge powers of 2. All you need is a bit of floating point arithmetic.如果您以这种方式构建问题,则无需计算 2 的巨大幂。您只需要一点浮点运算即可。

The following code works fairly well, but takes a good few seconds to produce answers when n is close to 10 7 :下面的代码运行得相当好,但当 n 接近 10 7时,需要几秒钟才能产生答案:

def power_of_2_with_prefix(n):
    # Find the minimum integer k such that the digits of 2^k
    # start with the digits of n
    from math import log10
    #
    # First deal with trivial cases
    assert type(n) is int
    if n == 1:
        return 0
    if n < 1:
        return -1
    #
    # Calculate mantissa range
    logmin = log10(n)
    logmax = log10(n+1)
    logmin -= int(logmin)
    logmax -= int(logmax)
    if logmax < logmin:
        logmax += 1
    #
    # Now find a power of 2 whose log10 mantissa lies in this range
    log2 = log10(2)
    # Make sure k is large enough to include all trailing zeros of n
    mink = log10(n) / log10(2)
    x = 1
    k = 0
    while not (logmin <= x < logmax and k >= mink):
        x += log2
        if x >= 1:
            x -= 1
        k += 1
    return k

assert power_of_2_with_prefix(0) == -1
assert power_of_2_with_prefix(1) == 0
assert power_of_2_with_prefix(2) == 1
assert power_of_2_with_prefix(4) == 2
assert power_of_2_with_prefix(40) == 12
assert power_of_2_with_prefix(28584) == 74715
assert power_of_2_with_prefix(28723) == 110057
assert power_of_2_with_prefix(9999999) == 38267831

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM