需要输入Project Euler Q 8

时间:2013-12-31 07:23:20

标签: c++ arrays

有更好的方法吗?

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

3 个答案:

答案 0 :(得分:1)

如果实际上减慢了事情

  • 导致分支CPU执行的并行管道
  • 也如前所述,它将使结果无效
  • 无论您的解决方案与应有的解决方案相同(对于其他数字都不能)

在算法方面,您可以这样做:

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

    char a[]="7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450\0";
    
    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];
    
    • 当然代替值0 * 0 必须添加中性值= 1 !!!
    • 当然代替值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'];
          }
      
  3. AMD 3.2GHz,64位Win7,32位App 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 ms的分辨率 我更喜欢使用RDTSC或PerformanceCounter。

答案 1 :(得分:0)

除了评论中指出的错误外,没有必要进行多次乘法。如果从索引0的[0] * [1] * [2] * [3] * [4]的乘积开始,那么从[1]开始的产品是什么?旧结果除以[0]并乘以[5]。一次除法和一次乘法可能比4次乘法更快

答案 2 :(得分:0)

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

您还可以检查最旧的读数是否等于零。如果是,那么你将真正必须乘以所有五个当前数字,但如果不是 - 更好的方法是将先前的乘法结果除以最旧的数字并将其乘以最新的读数位。