【问题标题】:how can i reduce the execution time for this code [closed]如何减少此代码的执行时间 [关闭]
【发布时间】:2017-11-16 22:59:10
【问题描述】:

问题是用户输入 N,1

5     // N
1     // First line
2     // Second line ... to fifth
3 
4
5
3    // Q
0 4  // the two numbers a, b... Q times
1 3
2 2

输出将是

15 // from 0 to 4 : 1+2+3+4+5=15
9  // from 1 to 3 : 2+3+4=9
3  // from 2 to 2 : 3

如果 Q 和 N 都大 100000,我的代码执行时间超过 5 秒

#include <bits/stdc++.h>
#include<vector>
#include<numeric>
#include<functional>
using namespace std;

int main() {
int a,b,c,p1,p2,sum(0);
vector<int>t(0);
cin>>a;
for(int i(0);i<a;++i)
{
    cin>>b;
    t.push_back(b);
}
cin>>c;
for(int i(0);i<c;++i)
{
    sum=0;
    cin>>p1>>p2;
    sum=accumulate(t.begin()+p1,t.begin()+p2+1,0);
    cout<<sum<<endl;
}
return 0;
}

【问题讨论】:

  • 如果您的程序正常运行并且只有性能问题,codereview.stackexchange.com 将是一个更好的提问位置。请务必阅读该网站的提问指南:codereview.stackexchange.com/help/asking
  • 提示:不要存储实际数字,存储运行总数S(i)==x_0 + ... + x_i。那么从ab 的总和就是S(b) - S(a-1)
  • 我投票结束这个问题,因为工作代码的改进属于 CodeReview.StackExchange.com

标签: algorithm c++11 sum


【解决方案1】:

与其将数字保存在数组中并每次都计算总数,不如计算一个运行总和并将该总和存储在数组中。

例如,给定数字 [1, 2, 3, 4, 5],您的 t 向量将包含 [1, 3, 6, 10, 15]。您可以轻松地修改您的代码来构建它:

int sum = 0;
t.push_back(sum);  // see discussion below
for(int i(0);i<a;++i)
{
    cin>>b;
    sum += b;
    t.push_back(sum);
}

然后,当被要求求和时,只需从结束索引处的数字中减去 开始索引之前的值即可。例如:

1,3 : result = t[3] - t[0]
2,2 : result = t[2] - t[1]

如果起始索引为 0,那么您根本不会减去任何内容。我首先将 0 和推到向量的原因是为了处理p1 = 0 时的情况。否则我将不得不特例。 (感谢@max66 的建议。)

您的计算循环变为:

for(int i(0);i<c;++i)
{
    cin>>p1>>p2;
    sum=t[p2+1] - t[p1];
    cout<<sum<<endl;
}

【讨论】:

  • 简化(恕我直言):在推回循环之前添加一个零(t.push_back(0)); result 变为 result = t[p2+1] - t[p1];;避免if ( p1 &gt; 0 ) 测试。
  • 实际上这种方法是有效的,但是如果 Q 和 N 真的很大,它需要 5 秒以上才能执行,我认为它不可能在 5 秒内执行,因为这个练习正在进行一个在线法官,所以当它输入一个大的 Q 和 N 时,它会给出 TLE,这意味着执行时间超出了限制
  • @HaytamRahimi:考虑将你的向量预先分配到a+1的大小。这将避免在向量增长时重新分配内存。如果这仍然太慢,那么用预先分配的数组替换你的向量。
猜你喜欢
  • 2021-12-02
  • 2019-12-14
  • 2016-07-24
  • 1970-01-01
  • 2011-04-08
  • 2015-05-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多