【问题标题】:c++ - hackerrank project euler #1 terminated due to timeoutc++ - 由于超时,hackerrank 项目 euler #1 终止
【发布时间】:2015-06-17 08:38:58
【问题描述】:

关于这个话题有很多讨论。我经历了它们,但没有任何帮助。

这个问题看起来很简单:

如果我们列出所有小于 10 且是 3 的倍数的自然数,或者 5,我们得到3、5、6和9。这些倍数之和是23。

求 N 以下所有 3 或 5 的倍数之和。

输入格式 第一行包含表示测试次数的 T 案例。接下来是 T 行,每行包含一个整数 N。

输出格式 对于每个测试用例,打印一个整数,表示 N以下所有3或5的倍数之和。

约束 1≤T≤10^5 1≤N≤10^9

但是,对于两个测试用例,很可能是输入量很大的测试用例,我的代码由于超时而终止。

这是我的代码:

int main() {
    unsigned long long int n,t;
    unsigned long long int sum;
    cin>>t;
    while(t--)
        {
        sum=0;
        cin>>n;
        for(unsigned long long int i=3;i<n;i++){
            if(i%3==0 || i%5==0){
                sum+=i;
            }
        }
        cout<<sum<<"\n";
    }

    return 0;
}

为什么即使使用 unsigned long long int 也不能​​处理大量输入?

【问题讨论】:

  • 我不知道这是否是最好的,但您可以为3 设置一个循环,它只会迭代您当前实现的三分之一,并且没有if 也检查。想一想。
  • 您需要使用大量数据进行分析,以找出大部分时间都花在了哪里。
  • 求助于数学。您正在寻找 3 的所有倍数的总和加上 5 的所有倍数的总和减去 15 的所有倍数的总和,所有这些都可以在恒定时间内计算出来。

标签: c++ timeout


【解决方案1】:
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;


int main() {
    /* Enter you`enter code here`r code here. Read input from STDIN. Print output to STDOUT */  
    long long int t, N, i=0, sum3=0, sum5=0, sum35=0;
    cin >> t;
    while(i<t){
        cin >> N;
        N=N-1;
        sum3 = 3 * ((N/3) * ((N/3) + 1) ) / 2;
        sum5 = 5 * ((N/5) * ((N/5) + 1) ) / 2;
        sum35 = 15 * ((N/15) * ((N/15) + 1) ) / 2;       
        cout << sum3 + sum5 - sum35 << endl;
        sum3=sum5=sum35=0;
        i++;
    }


    return 0;
}

【讨论】:

    【解决方案2】:

    我在python中试过,你可以检查一下

    def multiple(n): 
        return n*(n+1)/2
    def sum(n): 
        return multiple(n/3)*3 + multiple(n/5)*5 - multiple(n/15)*15
    for i in xrange(int(raw_input())):
        n = int(raw_input()) - 1
        print sum(n)
    

    【讨论】:

      【解决方案3】:

      我建议使用两个加法循环并消除昂贵的% 运算符。

      假设所有能被 3 整除的数字也是所有加了 3 的数字。因此,与其测试一个数字的可被 3 整除并将它们相加,只需将 3 的倍数相加即可。

      例如:

      for (int i = 0; i < n; i = i + 3)
      {
        sum += i;
      }
      

      如果您还包括 5 的循环,您将得到所有值的总和。

      另外,减去 15 的倍数。

      另一方面,应用一点代数和微积分,您可以简化公式,然后实现它。

      一些分析

      可被 3 整除的值的数量少于 N/3。所以对于 N = 13,有 3 的 4 个倍数:3、6、9、12。所以 limit 是 N/3。

      通过代数分解,我们看到 N = 13 的数字是:

      [1] (3 * 1) + (3 * 2) + (3 * 3) + (3 * 4)  
      

      分解出 3 的常见乘积:

      [2]  3 * ( 1 + 2 + 3 + 4)
      

      查看等式 [2],得出 3 * sum(1..N)。

      使用formula for summation

      (x * (x + 1)) / 2
      

      方程可以简化为:

      [3] 3 * ( 4 * (4 + 1) ) / 2
      

      或者用 N/3 替换总值,这个公式得出:

      [4] 3 * ((N/3) * ((N/3) + 1) ) / 2
      

      等式 [4] 的简化留给读者作为练习。

      【讨论】:

        【解决方案4】:

        问题超时可能设置为不允许像您这样的蛮力算法的值。您可以使用连续整数求和的封闭公式和德摩根定律,在恒定时间内计算任意给定 N 值的总和。

        【讨论】:

          猜你喜欢
          • 2018-10-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-03-03
          • 1970-01-01
          • 2018-03-26
          • 2019-07-26
          相关资源
          最近更新 更多