需要您的输入Project Euler Q 8

Need your input Project Euler Q 8

本文关键字:Euler Project 输入      更新时间:2023-10-16

有更好的方法吗?

http://projecteuler.net/problem=8

我添加了一个条件来检查数字是否大于6(消除小产品和0)

#include <iostream>
#include <math.h>
#include "bada.h"
using namespace std;
int main()
{
int badanum[] { DATA };
int pro=0,highest=0;
for(int i=0;i<=996;++i)
{
if (badanum[i]>6 and badanum[i+1] > 6 and badanum[i+2] >6 and badanum[i+3]>6 and badanum[i+4]>6)
{
pro=badanum[i]*badanum[i+1]*badanum[i+2]*badanum[i+3]*badanum[i+4];
if(pro>highest)
{
cout << pro << " " << badanum[i] << badanum[i+1] << badanum[i+2] << badanum[i+3] << badanum[i+4] << endl;
highest = pro;
}
pro = 0;
}
}
}

bada.h只是一个包含1000位数字的文件。

#DEFINE DATA <1000 digit number>

http://projecteuler.net/problem=8

如果真的减慢了

  • 导致CPU执行的并行管道分支
  • 如前所述,它将使结果无效
  • 你的解决方案是否与它应该的一样并不重要(对于其他数字,它不能)

在算法方面,你可以做:

  1. 如果你有足够快的除法,你可以降低计算数

    char a[]="7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450";
    int i=0,s=0,m=1,q;
    for (i=0;i<4;i++)
    {
    q=a[i  ]-'0'; if (q) m*=q;
    }
    for (i=0;i<996;i++)
    {
    q=a[i+4]-'0'; if (q) m*=q;
    if (s<m) s=m;
    q=a[i  ]-'0'; if (q) m/=q;
    }
    
  2. 您还可以为mul、div操作创建一个表,以提高的速度(但并非所有情况下都更快)

    int mul_5digits[9*9*9*9*9+1][10]={ 0*0,0*1,0*2, ... ,9*9*9*9*9/9 };
    int div_5digits[9*9*9*9*9+1][10]={ 0/0,0/1,0/2, ... ,9*9*9*9*9/9 };
    // so a=b*c; is rewritten by a=mul_5digits[b][c];
    // so a=b/c; is rewritten by a=div_5digits[b][c];
    
    • 当然,必须添加中性值=1,而不是值0*0
    • 当然,i/0必须添加中性值=i,而不是值!!!

      int i=0,s=0,t=1;
      for (i=0;i<4;i++)
      {
      t=mul_5digits[t][a[i  ]-'0'];
      }
      for (i=0;i<996;i++)
      {
      t=mul_5digits[t][a[i+4]-'0'];
      if (s<t) s=t;
      t=div_5digits[t][a[i  ]-'0'];
      }
      

AMD 3.2GHz、64位Win7、32位应用程序BDS2006 C++上的运行时间测量:

0.022ms classic approach
0.013ms single mul,div per step (produce false outut if there is none product > 0 present)
0.054ms tabled single mul,div per step (is slower for my setup)

PS

所有的代码改进都应该被衡量,这样你们就可以看到你们是否真的加快了速度
因为对一个编译器/平台/计算机来说更快的东西对另一个来说可能更慢
使用至少0.1毫秒的分辨率
我更喜欢使用RDTSC或PerformanceCounter。

除了注释中指出的错误外,不需要那么多乘法运算。如果您从索引0的[0]*[1]*[2]*[3]*[4]的乘积开始,那么从[1]开始的乘积是什么?旧结果除以[0]并乘以[5]。一次除法和一次乘法可能比4次乘法更快

您不需要一次存储所有数字。仅当前的五个变量(使用循环重写的数组),一个变量存储当前问题结果,一个用于存储最新的乘法结果(见下文)。如果输入中的数字数量会增加,你就不会遇到任何内存问题。

此外,您还可以检查读取的最旧数字是否等于零。如果是,那么你真的必须将当前的五个数字相乘,但如果不是,更好的方法是将之前的相乘结果除以最旧的数字,再乘以最近读取的数字。