欧拉23号项目C++
Project Euler 23 C++
我一直在研究欧拉#23项目。
这是任务:
问题 23
完美数是其适当除数之和正好等于该数的数字。例如,28 的适当除数之和将是 1 + 2 + 4 + 7 + 14 = 28,这意味着 28 是一个完美数。
如果一个数的适当除数之和小于 n,则称为不足,如果该和超过 n,则称为丰度。
由于 12 是最小的丰度数,1 + 2 + 3 + 4 + 6 = 16,因此可以写为两个丰度数之和的最小数是 24。通过数学分析可以证明,所有大于28123的整数都可以写成两个丰度数之和。然而,这个上限不能通过分析进一步降低>即使已知不能表示为两个丰度之和的最大数小于这个极限。
找到所有正整数的总和,这些正整数不能写成两个丰数字的总和。
#include<iostream>
using namespace std;
int main() {
long long sum;
int numbers[30000];
int ab[7000];
for(int i=0;i<7000;i++)
ab[i]=0;
//array of numbers
for(int i=0; i<28123;i++)
numbers[i]=i+1;
//abundant numbers
int abud_counter=0;
for(int i=1; i<28124;i++){
//factors
int temp=0;
for(int j=2;j<=i/2;j++) {
if(i%j==0)
temp=temp+j;
}
temp=temp+1;
if(temp > i) {
ab[abud_counter]=i;
numbers[i-1]=0;
abud_counter=abud_counter+1;
if(abud_counter>6965)
break;
}
}
//all shit
int array2[7000];
for(int i=0; i<6965; i++)
array2[i]=ab[i];
int k=0;
for(int i=0;i<6965;i++) {
for(int j=0;j<6965;j++) {
if(ab[i]+array2[j]==numbers[ab[i]+array2[j]-1]) {
numbers[ab[i]+array2[j]-1]=0;
}
}
}
sum=0;
for(int i=0; i<28123; i++) {
sum = sum+numbers[i];
}
cout<<sum;
return 0;
}
我得到的总价值是4178876。正确答案是 4179871.我花了 10 个小时查看我的代码,但找不到错误。我应该更改什么来更正错误?我的答案很接近。提前致谢
附言。我是学习新手。运行时间为 1.3 秒,任何优化也将很有用。
发布的代码中存在一些问题,除了一些低效率和滥用幻数。
当填充丰数组时,number
数组的某些元素被错误地归零。
if(temp > i) {
ab[abud_counter]=i;
numbers[i-1]=0; // <----- Why? Remove this line.
abud_counter=abud_counter+1;
if(abud_counter>6965)
break;
}
当我尝试这个程序时,由于这一行,我得到了一个分段错误
for(int i=0;i<6965;i++) {
for(int j=0;j<6965;j++) {
if(ab[i]+array2[j]==numbers[ab[i]+array2[j]-1]) {
// ^^^^^^^^^^^^^^^^^^
numbers[ab[i]+array2[j]-1]=0;
}
}
}
numbers
有 30000 个元素,但ab[i]
和array2[j]
的值最多可以达到 28123。
顺便说一句,array2
是多余的,它只是ab
的副本.
生成正确 4179871 值的算法的修改版本可能如下所示
#include <array>
#include <iostream>
#include <vector>
long sum_of_dividends(int n)
{
long sum{1};
int i = 2;
for (int j = n; i < j; ++i)
{
if ( n % i == 0 )
{
sum += i;
j = n / i;
if (i == j)
break;
sum += j;
}
}
return sum;
}
int main()
{
std::vector<int> abundants;
abundants.reserve(7000);
constexpr int max_value = 28123;
for (int i{1}; i <= max_value; ++i)
{
if (sum_of_dividends(i) > i)
abundants.push_back(i);
}
std::array<bool, max_value> are_sums{};
for (unsigned i{}; i < abundants.size(); ++i)
{
for (unsigned j{i}; ; ++j)
{
long k = abundants[i] + abundants[j];
if (k >= max_value)
break;
are_sums[k] = true;
}
}
long sum{};
for (int i{}; i < max_value; ++i)
if (!are_sums[i])
sum += i;
std::cout << sum << 'n';
}
虽然前面的实现利用了更快的方法来计算数字的股息之和,但处理时间的大幅改进需要一种不同的方法来搜索丰富的数字。
以下片段利用了一个类似于埃拉托色尼筛子的想法,而不是搜索范围内每个数字的股息,它只是对适当数字的每个股息求和。
std::vector<int> abundants;
std::vector<long> dividends_sums(max_value + 1, 1);
for (int i{2}; i <= max_value; ++i)
{
for (int j{i * 2}; j <= max_value; j += i)
dividends_sums[j] += i;
if (dividends_sums[i] > i)
abundants.push_back(i);
}
可以在此处看到此修改的影响。
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 无法在 CLion 中构建 C++ 项目
- 运行同一解决方案的另一个项目的项目
- CMake-按正确顺序将项目与C运行时对象文件链接
- 如何在选项卡视图Qt中设置一个新项目,并保存以前的项目
- 欧拉项目#8答案是大以获得有效答案
- 从链接列表c++中删除一个项目
- CMake项目Boost库错误:Boost/config/compiler/gcc.hpp:165:10:致命错误:cs
- 既然存在危险,为什么项目要使用-I include开关
- cmake在我的项目中所需的所有静态库都不成功
- QT通过C++添加映射QML项目
- 我的项目不会像"undefined reference to `grpc::g_core_codegen_interface'"那样使用未定义的引用错误进行编译
- 在linux上调试巨大的C++项目
- 在其他文件中创建类时在 c++ 项目中不起作用
- 使外部项目可用于find_package CMake
- 在子目录中使用target_sources()命令时用于单元测试(qtest)的项目结构
- 使用外部SDK工具链文件在VisualStudio上生成项目编译错误
- 如何维护资源管理器项目视图中当前可见的项目列表
- 错误-我无法在VS2019中打开新的Qt项目
- 你能检查一下为什么在这个代码中从链接列表中删除项目不起作用吗