接收输入数字,找到一种有效的算法来查找是否存在和 以4的幂数表示的一对数字等于该数字。 例如:
Input: val=337
x=3^4=81
y=4^4=256
81+256=337
另一个例子是:
val=641
x=5^4=625
y=2^4=16
val=x+y=641
我正尝试使用C代码解决此问题。
我考虑了这个问题,我只是想对所有可能的数字进行迭代,使它们的4的幂将提供一个小于请求输入的数字,并检查所有可能数字的总和是否与此匹配数字。
似乎效率不高。 拜托,你能帮忙吗? 谢谢
答案 0 :(得分:1)
#include<stdio.h>
#include<math.h>
long long int binarySearch(long long int limit){
long long int low = 1,high = sqrt(sqrt(limit));
long long int mid = 0;
long long int ans = 0;
while(low <= high){
mid = low + (high - low) / 2;
long long int raiseToFour = mid * mid * mid * mid;
if(raiseToFour > limit) high = mid - 1;
else if(raiseToFour < limit){
low = mid + 1;
ans = mid;
}else{
ans = mid;
break;
}
}
return ans;
}
int main(void) {
long long int sum = 337;
long long int i;
long long int left = 1, right = binarySearch(sum);
while(left <= right){
long long int leftFourthPower = left * left * left * left;
long long int rightFourthPower = right * right * right * right;
if(leftFourthPower + rightFourthPower == sum){
printf("%lld ^ 4 + %lld ^ 4 = %lld",left,right,sum);
break;
}else if(leftFourthPower + rightFourthPower > sum){
right--;
}else{
left++;
}
}
return 0;
}
它给出:
3 ^ 4 + 4 ^ 4 = 337
1
到sqrt(sqrt(sum))
进行二进制搜索,以找到幂数最接近sum
的4 次幂的数字。 left
和right
,其中right
是二进制搜索函数的上限),找到第4个 幂加起来等于给定的和。如果总和超过,则我们递减right
指针,如果它小于给定的总和,则增加left
指针。答案 1 :(得分:0)
一种简单的启发式方法是检查输入sqrt(sqrt(n))
小于或等于n
的值。因此,该算法的复杂度为"choose 2 from sqrt(sqrt(n))" = O(sqrt(n))
。
答案 2 :(得分:0)
解决方案1:O(n)
的时间和O(n)
的空间
伪代码
x
,将其存储在哈希表x^4
x
,检查val-x^4
是否在哈希表中如果第2步找到匹配项,则存在满足要求的一对。
复杂度
用于构建哈希表的复杂度为O(n)
,而用于扫描的复杂度为O(n)
。此外,所需的额外空间为O(n)
。
实施
对于 c 实现,可以使用unordered_set
。
x^4+x^4=val
在输入中x
仅出现一次)。 解决方案2:O(n*log(n))
时间和O(1)
空间
伪代码
x
,二进制搜索sqrt(val-x^4)
如果第2步找到匹配项,则存在满足要求的一对。
自慰
排序的复杂度为O(n*log(n))
。每次二进制搜索需要O(log(n))
时间并执行n
次。因此,整体时间复杂度为O(n*log(n))
实施
对于 c 实现,可以使用qsort
。
答案 3 :(得分:0)
可以使用以下公式快速完成此操作:
我们可以计算出幂4的最大数,这就是开始。 为了最大程度地减少for循环,我们可以在数目减半时结束。解决方案还支持其他功能。 下面的完整代码(C#)
public static void Main(string[] args)
{
const int raisedPow = 4;
long num = 3262811042;
Console.WriteLine("{0}", num);
int start = (int) Math.Pow(Math.E, (Math.Log(num) / Math.Log(Math.E)) / raisedPow);
int end = (int) Math.Pow(Math.E, (Math.Log(num/2) / Math.Log(Math.E)) / raisedPow);
int y = -1;
int stepCount = 0;
for (int i = start; i>end;i--)
{
stepCount++;
long rest = (long) (num - (Math.Pow(i, raisedPow)));
int j = (int) Math.Round(Math.Pow(Math.E, (Math.Log(rest) / Math.Log(Math.E)) / raisedPow));
if (rest - (Math.Pow(j, raisedPow)) == 0)
{
Console.WriteLine("{0} {1}", i, j);
y = j;
}
}
Console.WriteLine("steps {0}", stepCount);
if (y == -1) Console.WriteLine("No Solution");
Console.ReadKey();
}