mercredi 19 juillet 2017

std::sort and std::max_element result in different outputs?

The following code has been written to solve this CodeChef problem.

#include <iostream>
#include <vector>
#include <algorithm>

using std::cout;
using std::cin;
using std::endl;
using std::vector;

//  function to find desired sum
//  position is the index of the current element
//  first is the index of the element one before the first element of the 
    row
//  last is the index of the last elment in the row
//  example:
//      1
//      1 2(first)
//      4 1 2(last) <-- current row
//      2 3 1 1
void pyramid_sum (vector<unsigned int> &sum, vector<unsigned int> &pyramid, 
        const unsigned int partial_sum = 0, const int first = -1, 
        const int last = 0, const int position = 0) {

    const int row_size = last - first;

    //if block only executed while processing last row
    //last element added and control returns to function call
    if (static_cast<unsigned int>(last) == (pyramid.size() - 1)) {
        sum.push_back(partial_sum + pyramid[position]);
        return;
    }

    //function recursively calls itself to calculate every sum possible and 
    //stores it in sum
    pyramid_sum (sum, pyramid, partial_sum + pyramid[position], last, 
            last + row_size + 1, position + row_size); 
    pyramid_sum (sum, pyramid, partial_sum + pyramid[position], last, 
            last + row_size + 1, position + row_size + 1); 
}

// function to find total number of element depending on number of rows in 
// pyramid
unsigned int pyramid_size (unsigned int rows) {
    unsigned int total = 0;
    while (rows) {
        total += rows;
        rows--;
    }
    return total;
}

int main() {
    vector<unsigned int> pyramid, sum;
    unsigned int count, rows, buffer;
    cin >> rows;
    for (unsigned int i = 0; i != pyramid_size(rows); i++) {
        cin >> buffer;
        pyramid.push_back(buffer);
    }
    pyramid_sum(sum, pyramid); 
    std::sort(sum.rbegin(), sum.rend());
    cout << *(sum.cbegin()) << '\n';
    //cout << *std::max_element(pyramid.begin(), pyramid.end()) << '\n';
    return 0;
}

The program works as follows:

  1. Accept input and calculates every possible sum (according to the
    rules mentioned in the problem description).
  2. All possible values are stored in vector<unsigned int> sum.
  3. Maximum value stored in vector<unsigned int> sum is displayed.

The maximum value can be determined in two ways:

Method 1: use std::sort to sort vector<unsigned int> sum in descending order and display the first element.

std::sort(sum.rbegin(), sum.rend());
cout << *(sum.cbegin()) << '\n';

Method 2: use std::max_element to determine the largest element and display it.

cout << *std::max_element(pyramid.begin(), pyramid.end()) << '\n';

According to my understanding the result of both the methods should be the same (other than the fact that using method 1 would result in a sorted vector).


However the two methods result in different outputs for the following input (the code was compiled using gcc and the online CodeChef IDE):

4
1
1 2
4 1 2
2 3 1 1

Method 1 output:

9

Method 2 output:

4

(Method 1 output is correct according to CodeChef examples.)

Is it my understanding or my code which is flawed?

I realise that we aren't allowed to ask multiple questions in one post, but, I would also like to know what is making my program slow? (the program times out when I submit it to CodeChef)

Aucun commentaire:

Enregistrer un commentaire