【问题标题】:arithmetic overflow in codility test代码测试中的算术溢出
【发布时间】:2014-06-27 20:26:14
【问题描述】:

我做了代码演示测试“NumberOfDiscIntersections”: https://codility.com/programmers/lessons/4

我得到:性能 = 100% 和正确性 87%

除一项外的所有测试都正常:

overflow 
arithmetic overflow tests

为什么我的long long,还不够?我不知道出了什么问题!

#include <algorithm>


int solution(const vector<int> &A) 
{
    // write your code in C++11
    vector<long long > vec_max;
    for(int i = 0; i < A.size(); ++i)
    {
        vec_max.push_back( A[i] + i );
    }
    std::sort(vec_max.begin(),vec_max.end()); // sort by max

    int step = 1;
    int counter = 0;
    for(int i = A.size() - 1; i > -1; --i)
    {
        std::vector<long long>::iterator low;

        int nb_upper = A.size() - ( lower_bound( vec_max.begin(),vec_max.end(), (long long) (i - A[i]) ) - vec_max.begin() );
        counter += nb_upper - step;
        ++step;
    }

    if (counter > 10000000)
    {
        return -1;
    }
    else
    {
        return counter;
    }
}

【问题讨论】:

  • 你还有一些int 变量。你确定它们都不会溢出吗?
  • 向下循环的替代方案:for(auto i=A.size(); i!=0;) { --i; ...} 并考虑@n-m 的评论。

标签: c++ algorithm


【解决方案1】:

如果 A 数组非常大,您最终可能会向计数器 int 变量添加大索引。 step 变量与之相比非常小

counter += nb_upper - step;

这很可能是您溢出变量的地方。

【讨论】:

  • 是的,“计数器的最大值”是每个圆盘都与每个圆盘相交,我没有想到,但是对于 100.000 个圆盘,这大约是 = 1 +2 + .. + 100.000 ~ (N^2 +N) / 2 ~ 5.000.050.000 这确实是溢出。我经常因为缺乏极端测试而被搞砸,这是代码教给我的一件事:)
  • 是的,如果您有一个自然数和作为输入数据,请使用高斯公式来估计复杂度(在 big-O 中,这将是 n^2 有界)并查看您对于 32 位整数只需要达到 n = 46340。我认为这要高得多,因为你写了 100k
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多