c++algorithmc++11gcc

Why does this C++ code give different output on different compilers?


I realize that there are many questions with this title on SO, but all of the ones I've found did things like i = ++i or f(f(f(x))), neither of which are in this code. It's an attempt at a backtracking solution to this. I have some experience with C but I've just started trying to pick up C++, and I've been doing Codeforces problems for practice. The snippet below is the main body of the program. main, which I have not shown, deals with input and output. I used global variables here for weights, answer, and max_depth in the interest of keeping each stack frame of solve as small as possible.

The input that's causing trouble is weights = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} and max_depth = 1000. When I compile this with g++ std=C++11 file.cpp, it gives "4 3 2 3 4 3 2 3 4 ... 3 2 1," which is the correct answer. When Codeforces compiles it, it gives "9 10 9 10 9 10 9 10...", which is incorrect. My guess is that the order that for(int i : weights) traverses the vector in is not defined by the standard, but even then, I don't see why it would make any difference. What am I missing?

#include <iostream>
#include <vector>
#include <sstream>

using namespace std;

string answer = "";
vector<int> weights; 
int max_depth;

bool solve(int left_scale, int right_scale, int last_added, int depth){
  bool is_left = (depth % 2) == 0;

  int new_weight;
  int weight_to_inc = is_left ? left_scale : right_scale;
  int weight_to_exceed = is_left ? right_scale : left_scale;

  if (depth == max_depth){
    return true;
  }


  for(int i : weights){
    if (i != last_added){
      new_weight = weight_to_inc + i;
      if (new_weight > weight_to_exceed){
        bool ans =  solve(is_left ? new_weight : left_scale,
                          is_left ? right_scale : new_weight,
                          i, depth + 1);
        if (ans){
          stringstream ss;
          ss << i;
          answer.append(ss.str() + " ");
          return true;
        }
      }
    }
  }

  return false;
}

void start_solve(void){
  if (solve(0, 0, 0, 0)){
    return;
  }

  answer = "";
}

(The full code that I submitted, if it makes any difference, is here.)

EDIT:

In case anyone stumbles on this looking for an answer to the Codeforces problem: the issue with this code is that "answer" is reversed. Changing answer.append(ss.str() + " ") to answer = ss.str() + answer is the shortest fix that gets it working.


Solution

  • Why does this C++ code give different output on different compilers?

    It doesn't give different output.

    When I compile this with g++ std=C++11 file.cpp, it gives "4 3 2 3 4 3 2 3 4 ... 3 2 1," which is the correct answer. When Codeforces compiles it, it gives "9 10 9 10 9 10 9 10...", which is incorrect.

    I believe you are misinterpreting your test results on the codeforces server.

    The correct answer is "9 10 9 10...".

    The output of your program is "4 3 2 3 4 3..." on both the codeforces server and your local workstation.

    So your algorithm is wrong, and the output of the program is consistent.

    You are mixing up the two fields on the test results "Output" and "Answer".

    Check your test results again.