我正在尝试创建一个有效的函数来生成所有powerful numbers的向量,直到某些bound
(最终我希望这个高达10 ^ 17或10 ^ 18,我认为它在64位无符号长long值的最大值范围内 - 2 ^ 64 - 1)。
我提出的最有效的方法发布在下面。我的问题是,是否有人有更好/更有效的建议。
当执行这个函数时,我有一个素数向量,直到同一个边界;我考虑过使用这个向量来计算强大的数字,但在撰写本文时我认为所显示的解决方案会更有效率。
std::vector<int> powerful(int bound){
int x,y,cnt,num;
std::vector<int>* pows = new std::vector<ull>;
for(int i = 4; i<bound;i++){
x = i;
y=3;
cnt = 0;
num = x;
while(x%2==0){
x/=2;
cnt++;
}
while ((y <= x) && (cnt != 1)) {
cnt = 0;
while (x % y == 0) {
x /= y;
cnt++;
}
y += 2;
}
if(cnt>1)
pows->push_back(num);
}
return *pows;
}
答案 0 :(得分:3)
这是一个递归+迭代解决方案,可以从其组成素数构建强大的数字:
#include <cstdlib>
#include <iostream>
#include <set>
#include <vector>
static const int bound = 1000;
static const std::vector<int> primes =
// I'm assuming you can create this by Sieve of Eratosthenes or similar
{ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, }; // up to sqrt(bound)
typedef std::vector<int>::const_iterator prime_iter;
void add_powerful(std::set<int>& p, int v,
prime_iter it, prime_iter end, int bound)
{
if (it == end) { // terminate the recursion
p.insert(v);
return;
}
add_powerful(p, v, it+1, end, bound);
for (v *= *it * *it; v <= bound; v *= *it)
add_powerful(p, v, it+1, end, bound);
}
int main()
{
auto p = std::set<int>{};
add_powerful(p, 1, primes.begin(), primes.end(), bound);
for (auto i: p) std::cout << i << std::endl;
return EXIT_SUCCESS;
}
add_powerful
通过素数递归,在每种情况下乘以v
乘以该素数的所有幂0,2,3,4,...(省略1)。
我的快速测试同意expected results高达1000。
答案 1 :(得分:1)
不是试图对一个数字进行反向工程以确定它是否是一个强大的数字,而是使用已知公式生成有力的数字:m = a^2 * b^3
(来自您的链接)
您可以增加a
和b
的值,以覆盖小于N的所有结果。
答案 2 :(得分:0)
在最小化操作次数方面,最有效的方法是通过其主要分解来生成所需的强大数字。优质分解是独一无二的,它们可以直接告诉您数字是否强大。给定一个小于或等于强大数字上界的平方根的素数列表,可以系统地生成所有不同的素数因子组合,从而产生一个范围内有力的数字。