黑客等级最小极大问题,最大和给出错误的负值

时间:2019-06-20 13:46:30

标签: c++ c++14

我目前正在Hackerrank上解决此问题: https://www.hackerrank.com/challenges/mini-max-sum/problem

在15个测试用例中,我仅通过了5个。问题出在最大和的输出上。

在代码中,首先我要找到向量中的最大和最小元素,用max和min表示。 minI和maxI是最小值和最大值的指标。

在计算最大和时,我将arr [minI] = 0(因此向量简化为将给出最大和的元素)。一旦获得最大和,我就把arr [minI] = min,从而恢复原始向量。然后,我通过将arr [maxI] = 0重复该过程;通过这种方式,可以获得n-1个元素的最小和最大和。我知道这很难理解,但是任何人都可以在这里帮助我解决问题。

我尝试使用arr.erase()和arr.insert(),但这使我陷入了索引编制问题。

void miniMaxSum(vector<int> arr) {
int max = arr[0];
int min = arr[0];
int minI = 0;
int maxI = 0;
  for (int i = 0; i < arr.size(); i++) {
    if(arr[i] > max){
        max = arr[i];
        maxI = i;
    }
    if(arr[i] < min){
        min = arr[i];
        minI = i;
    }
  }


  arr[minI] = 0;
  int maxsum = 0;
  for(int i = 0; i<arr.size(); i++){
      maxsum += arr[i];
  }

  arr[minI] = min;


  arr[maxI] = 0;
  int minsum = 0;
  for(int i = 0; i<arr.size(); i++){
      minsum += arr[i];
  }


  cout << minsum << " " << maxsum;
}

例如,一个测试用例的输入是:

140537896 243908675 670291834 923018467 520718469

以上输入的正确答案是: 1575456874 2357937445

我对以上输入的回答是: 1575456874 -1937029851

2 个答案:

答案 0 :(得分:0)

显然,在此平台上,int的长度为32位,这意味着它的范围在-21474836472137483647之间。溢出最大值是未定义的行为。

对于您介绍的测试用例来说,将int更改为long long似乎就足够了,但是问题可能需要更大的数字,并且您需要确定如何对更大的数字进行计算。

答案 1 :(得分:0)

加正整数后的负和几乎总是可以查明问题所在:您正在溢出。

此问题有一个约束条件:

1 <= arr[i] <= 10^9

当您添加四个接近10 ^ 9的数字时,您溢出了一个32位整数。因此,您需要切换到更大的数据类型-uint64_t是一个不错的选择。

注意:该问题要求五个元素中恰好有四个元素的最小和最大和,这意味着需要排除一个元素。因此,如果从五个元素的总数中减去最小的元素,则总和将最大。当您减去最大元素时,总和将很小。