Fu Ge respuesta 2020-09-13:
Primero determine el rango de b, el rango de b debe estar en [2, logN]. Luego, recorra b para encontrar el rango de a. Si la longitud del rango es igual a 0, significa que el entero positivo es a elevado a b.
1. Atraviese el rango b. Encuentre a por dicotomía. El rango inicial de a es [2, logN]. 2 elevado a 400 toma 5 segundos. [Con código]
2. Recorre el rango de b. Optimice la dicotomía para encontrar a, el rango inicial de a es [2, el resultado de la a anterior]. 2 elevado a 10,000 toma 5 segundos. [Hay código]
3. Debería haber una solución más optimizada, pero no la esperaba por el momento. 【Sin código】
Debido a que se usan números enteros grandes, están escritos en Python. el código se muestra a continuación:
#!/usr/bin/python3
import time
from functools import wraps
def _get_sqrt_range(num, right, exp=2):
"""
求num的exp开方,exp是指数,num是结果。求底数。
Args:
num: 大于等于0并且是整数。
right: 大于等于0并且是整数。右边界。
exp: 大于等于0并且是整数。
Returns:
返回元组,表示一个开方范围。
Raises:
IOError: 无错误。
"""
left = 1
if num == 0:
return 0, 0
if num == 1:
return 1, 1
if num == 2 or num == 3:
return 1, 2
while True:
mid = (left + right) // 2
if mid ** exp > num:
right = mid
if left ** exp == num:
return left, left
if left + 1 == right:
return left, right
elif mid ** exp < num:
left = mid
if right ** exp == num:
return right, right
if left + 1 == right:
return left, right
if mid == 1:
return 1, 2
else:
return mid, mid
def get_log_range(num, basenum):
"""
求对数范围。
Args:
num: 数,大于等于1并且是整数。
basenum: 底数,大于等于2并且是整数。
Returns:
返回结果。对数范围。
Raises:
IOError: 无错误。
"""
if num == 1:
return 0, 0
else:
n = 0
ism = 0
while num >= basenum:
if ism == 0 and num % basenum != 0:
ism = 1
n += 1
num //= basenum
return n, n + ism
def timefn(fn):
"""计算性能的修饰器"""
@wraps(fn)
def measure_time(*args, **kwargs):
t1 = time.time()
result = fn(*args, **kwargs)
t2 = time.time()
print(f"@timefn: {fn.__name__} took {t2 - t1: .5f} s")
return result
return measure_time
@timefn
def is_power1(num):
"""
判断n是否是一个数的幂次方形式。
Args:
num: 大于等于0并且是整数。
Returns:
返回结果。true是幂数
Raises:
IOError: 无错误。
"""
if num <= 3:
return False
else:
log_range = get_log_range(num, 2)
if log_range[0] == log_range[1]:
return True
expmax = log_range[0]
expmin = 2
exp = expmin
sqrt = 0
right = 2 ** (1 + log_range[0] // 2)
while exp <= expmax:
sqrt = _get_sqrt_range(num, right, exp)
# right = sqrt[0]#缩小右边界范围
if sqrt[0] == sqrt[1]:
return True
if sqrt == (1, 2):
return False
exp += 1
return False
@timefn
def is_power2(num):
"""
判断n是否是一个数的幂次方形式。
Args:
num: 大于等于0并且是整数。
Returns:
返回结果。true是幂数
Raises:
IOError: 无错误。
"""
if num <= 3:
return False
else:
log_range = get_log_range(num, 2)
if log_range[0] == log_range[1]:
return True
expmax = log_range[0]
expmin = 2
exp = expmin
sqrt = 0
right = 2 ** (1 + log_range[0] // 2)
while exp <= expmax:
sqrt = _get_sqrt_range(num, right, exp)
right = sqrt[0] # 缩小右边界范围
if sqrt[0] == sqrt[1]:
return True
if sqrt == (1, 2):
return False
exp += 1
return False
if __name__ == "__main__":
print("----2的400次方")
num = 2 ** 400 + 1
print(is_power1(num))
print(is_power2(num))
print("\r\n----2的10000次方")
num = 2 ** 10000 + 1
print(is_power2(num))
Los resultados de ejecutar el código son los siguientes: