我基本上需要一个函数,发现X是^ b的结果,并显示a和b,但我不能使用数学库中的任何可用方法。
答案 0 :(得分:0)
朴素解(伪代码),循环遍历a
(这是指数时间):
for (a = 2; a <= sqrt(X); ++a) {
b = round ( log ( X ) / log( a ) )
if (a^b == X) {
output solution
exit
}
}
output no solution found
更好的解决方案(伪代码),循环遍历b
(这是多项式时间):
for (b = 2; b <= log(X)/log(2); ++b) {
a = round ( exp ( log(X)/b ) )
if (a^b == X) {
output solution
exit
}
}
output no solution found
Python中更好的解决方案:
import math
def inv_power(x):
upper_limit = math.log(x)/math.log(2)
b = 2
while b <= upper_limit:
a = int(round( math.exp ( math.log(x)/b ) ) )
if a**b == x:
return a,b
b = b + 1
return None
好问题。我很失望,很多人都投了票。
答案 1 :(得分:0)
我假设整数(来自评论)所以没有蛮力我会试试这个:
使用Eratosthenes的筛子O(X.log(log(X)))
最多sqrt(X)
或半位X
个数1<<(bits(X)>>1)
来找到您需要的素数。
扫描所有找到的素数p(i)
并检查您可以将X
除以它的次数。 m=~X/ln(X); O(m)
强>
请记住n
的分割数量。如果n<=1
则忽略此素数p(i)
并继续下一个p(i+1)
。如果n>1
,则将素数p(i)
及其n
添加到某个列表中;
按list
降序排列n
现在扫描O(m.log(m))
以获取解决方案list
因此q<=m; O(q^2)
除以list
中的每个条目,现在以相同的方式检查X'=X/list[j].p^list[j].n
(仅使用具有相同X'
的条目)。如果您有n
,请停止检查并输出找到的结果(使用功率X'=1
,n
是所有使用的素数的乘法)。您需要检查具有相同root
的素数的所有组合,以便进行递归。如果找不到具有相同n
的条目组合而导致n
,则转移到具有不同条目的条目
X'=1
再次从n
开始。
递归可能如下所示:
X
其中 bool check(int X,int n,int j,int &a)
{
int i,x;
for (;(list[j].n==n)&&(j<list.size);j++) // scan all primes with the same `n`
{
for (x=X,i=0;i<n;i++) x/=list[j].p; // x=X/p^n
if (x==1) { a*=list[j].p; return true; }// stop you hit the result
if (check(x,n,j+1,a)) return true; // recursion
}
return false;
}
是要检查的数字,X
实际上是检查权限,n
是在找到的列表中开始输入(无需测试之前的条目,因为它们已经被检查过)并且j
是power的基础。如果找到解决方案,则返回true,否则返回false。
所以现在你只需检查所有找到的功率并输出/停止首先找到的解决方案:
a
您可以将其中一些步骤组合在一起,尤其是#1,#2 (甚至避免递归)。如果您需要浮点或定点方法或想要为整数添加一些额外的想法,请参阅和子链接:
这里非常类似 Q / A ,其中C ++解决方案涵盖了您的问题: