检查一个数字是不是可以表示为两个立方体的和的高效程序
Posted
技术标签:
【中文标题】检查一个数字是不是可以表示为两个立方体的和的高效程序【英文标题】:Efficient program to check whether a number can be expressed as sum of two cubes检查一个数字是否可以表示为两个立方体的和的高效程序 【发布时间】:2015-08-22 16:15:51 【问题描述】:我正在尝试编写一个程序来检查一个数字 N 是否可以表示为两个立方体的总和,即 N = a^3 + b^3
这是我的代码,复杂度为 O(n):
#include <iostream>
#include<math.h>
#define ll unsigned long long
using namespace std;
int main()
ios_base::sync_with_stdio(false);
bool flag=false;
ll t,N;
cin>>t;
while(t--)
cin>>N;
flag=false;
for(int i=1; i<=(ll)cbrtl(N/2); i++)
if(!(cbrtl(N-i*i*i)-(ll)cbrtl(N-i*i*i))) flag=true; break;
if(flag) cout<<"Yes\n"; else cout<<"No\n";
return 0;
由于code的时间限制是2s,这个程序是给TLE的吗?谁能建议一个更快的方法
【问题讨论】:
这个问题是从某位网上评委那里提炼出来的吗? 是的...一周前结束的竞赛问题 分享学分,因为这个问题不是你的创造。 【参考方案1】:我也在 StackExchange 中发布了这个,如果您认为重复,很抱歉,但我真的不知道这些是相同还是不同的板(Exchange 和溢出)。我的个人资料在这里看起来不同。
===========================
有一种更快的算法可以检查给定整数是否是两个立方体 n=a^3+b^3 的和(或差)
我不知道这个算法是否已知(可能是,但我无法在书籍或互联网上找到它)。我发现并用它来计算整数,直到 n
这个过程使用一个技巧
4(a^3+b^3)/(a+b) = (a+b)^2 + 3(a-b)^2)
我们事先不知道什么是“a”和“b”,那么什么是“(a+b)”,但我们知道“(a+b)”当然应该除以 (a ^3+b^3) ,所以如果你有一个快速素数分解例程,你可以快速计算 (a^3+b^3) 的每个除数,然后检查是否
(4(a^3+b^3)/除数 - 除数^2)/3 = 平方
当(如果)找到一个正方形时,你有 divisor=(a+b) 和 sqrt(square)=(a-b) ,所以你有 a 和 b。
如果没有找到正方形,则该数字不是两个立方体的总和。
我们知道除数
现在与其他算法进行一些比较 - 对于 n = 10^18,通过使用蛮力,您应该测试所有低于 10^6 的数字以知道答案。另一方面,要构建 10^18 的所有除数,您需要素数直到 10^9。
你可以放入 10^9 的不同素数的最大数量是 10 (2*3*5*7*11*13*17*19*23*29 = 5*10^9) 所以我们有 2^ 10-1 种不同的素数组合(组合除数)以在最坏的情况下进行检查,其中许多因限制而被丢弃。
为了计算素数,我使用了一个包含前 60.000.000 个素数的表格,它在这个范围内工作得很好。
米格尔·维利利亚
【讨论】:
【参考方案2】:要找到所有整数对 x 和 y 在立方时总和为 n,设置 x到小于n立方根的最大整数,设置y为0,如果立方和y重复加1小于n,如果立方和大于n,则从x中减1,否则输出该对,当x 和 y 交叉。如果只想知道有没有这样的一对,一找到就停下来。
如果您在编码此算法时遇到问题,请告诉我们。
【讨论】:
好吧,我觉得这个算法也在 O(n) 中,并且数字 N 是两个连续立方体的总和,例如 931^3 + 932^3,那么迭代次数将相等到最大整数..这可能效率低下..我确实想过这个 在循环的每一步中,x 会递减或 y 递增,因此该算法需要时间 O(cbrt n ).以上是关于检查一个数字是不是可以表示为两个立方体的和的高效程序的主要内容,如果未能解决你的问题,请参考以下文章