需要一种方法来使此代码运行得更快
Need a way to make this code run faster
我正在尝试解决欧拉计划问题 401。他们唯一能找到解决它的方法就是蛮力。我已经运行了这段代码大约 10 分钟,没有任何答案。谁能帮我提出改进的想法。
法典:
#include <iostream>
#include <cmath>
#define ull unsigned long long
using namespace std;
ull sigma2(ull n);
ull SIGMA2(ull n);
int main()
{
ull ans = SIGMA2(1000000000000000) % 1000000000;
cout << "Answer: " << ans << endl;
cin.get();
cin.ignore();
return 0;
}
ull sigma2(ull n)
{
ull sum = 0;
for(ull i = 1; i<=floor(sqrt(n)); i++)
{
if(n%i == 0)
{
sum += (i*i)+((n/i)*(n/i));
}
if(i*i == n)
{
sum -= n;
}
}
return sum;
}
ull SIGMA2(ull n)
{
ull sum = 0;
for(ull i = 1; i<=n; i++)
{
sum+=sigma2(i);
}
return sum;
}
如果 a/b=c,你缺少一些分隔符,并且b
是a
的分隔符,那么c
也将是a
的分隔符,但c
可能大于floor(sqrt(a))
,例如 3> floor(sqrt(6)) 但除以 6。
然后你应该把你的floor(sqrt(n))放在一个变量中,并在for中使用变量,否则你重新计算它,这是非常昂贵的每个操作。
您可以进行一些简单的优化:
- 内联
sigma2
, - 在循环之前计算
floor(sqrt(n))
(但编译器可能无论如何都会这样做), - 预先计算从
1
到n
的所有整数的平方,然后使用数组查找而不是乘法
通过改变你的方法,你会获得更多。想想你想做什么 - 从 1 到 n 的所有整数的所有除数的平方求和。您按除数的划分对除数进行分组,但您可以在此总和中重新分组项。让我们按除数的值对除数进行分组:
1
将所有内容除以,因此它将在总和中出现n
次,得出1*1*n
总数,2
除以偶数,将出现n/2
(整数除法!),得到2*2*(n/2)
总数,k
......将带来k*k*(n/k)
总数。
因此,我们应该将k*k*(n/k)
从1
k
加起来n
.
考虑一下问题。
您尝试的暴力破解方式显然不是一个好主意。
你应该想出更好的东西... 没有任何方法可以使用一些不错的素数分解方法来加快计算速度吗?没有任何递归模式吗?试着找点东西...
您可以执行的一个简单优化是,数字中将有许多重复的因素。
所以首先估计有多少个数字 1 是一个因子(所有 N 个数字)。
在多少个数字中,2 是一个因子 ( N/2 )。
。
其他人也是如此。
只需将它们的平方乘以它们的频率即可。
然后,时间复杂度应立即降低到O(N)
有明显的微优化,例如++i而不是i++或将floor(sqrt(n))从循环中取出(这是两个浮点运算,与循环中的其他整数运算相比非常昂贵),并且只计算n/i一次(使用虚拟变量,然后计算虚拟人的平方)。
算法中也有相当明显的简化。例如 SIGMA2(i) = SIGMA2(i-1) + sigma2(i)。但是不要使用递归,因为你需要一个非常大的数字,这是行不通的,你的堆栈内存会耗尽。使用循环而不是递归。改进的潜力很大。
好吧,还有一个更大的问题 - 10^15 有 15 位数字。这个数字的平方有 30 位数字。你不可能把它存储到无符号的长长,我想到大约 20 位数字。所以你需要以某种方式使用模 10^9(作业的结束)并获得额外的空间来计算......
例如,使用蛮力时,每隔百万个数字打印出临时结果,让您了解接近最终结果的速度。盲目等待10分钟不是一个好主意。
- 我的代码运行良好,但在游戏循环中中断
- 通过窗口从C++代码运行 WSL 命令
- 如何使用 lldb 查找我的代码运行的位置
- 无法在 VS Code 上使用代码运行程序运行C++文件
- 我的代码运行良好,但现在当尝试将其制作成模板时,我遇到了许多看似无关的错误。这是怎么回事?
- Visual Studio代码运行环境
- 如何从C++代码运行自定义 GPU tensorflow::op?
- 在 ZeroMQ 中绑定订阅者套接字并连接发布者套接字会在代码运行时给出错误.为什么
- 代码运行缓慢
- .NET CORE 2 DLL引用带有C 代码运行时错误
- C++ 中控制台代码运行时的分段错误
- C++ 菜单代码 - 运行另一个类
- 以下代码运行后,如何在程序再次运行之前清除用户声明的变量 empName
- 当我使用此合并排序代码运行时,输出错误
- 有哪些优化技巧可以使我的代码运行得更快
- 使 C 代码能够作为C++代码运行
- 错误代码LNK1561阻止我的代码运行
- 如果我用代码块编译代码,为什么我的代码运行速度更快
- 更改Linux用户从C/C 代码运行时间
- 为什么这段代码运行这么慢