Paired Up Infinite Loop behavior

My solution to “Paired Up” follows.

int main()
{
    setIO("pairup");
    int N; cin >> N;
    vt<pi> pairs(N);
    F0R(i, N) {
      cin >> pairs[i].s >> pairs[i].f;
    }
    sort(all(pairs));

    int i = 0, j = N-1;
    int amt = 0;
    while (i <= j) {
      amt = max(pairs[i].f + pairs[j].f, amt);

      //update cnts
      cerr << pairs[i].s << " " << pairs[j].s << " ";
      int rem = min(pairs[i].s, pairs[j].s);
      pairs[i].s -= rem;
      pairs[j].s -= rem;
      cerr << rem << " " << pairs[i].s << " " << pairs[j].s << endl;
      //assert(pairs[i].s >= 0 && pairs[j].s >= 0);
      //if (pairs[i].s < 0 || pairs[j].s < 0) break;

      //at least 1 pointer should advance
      if (pairs[i].s == 0) {
        cerr << "i is moving" << endl;
        i++;
      }
      if (pairs[j].s == 0) {
        cerr << "j is moving" << endl;
        j--;
      }
    }
    cout << amt << endl;
}

In the sample input when i and j are both 1, rem = 2 as expected. However, when I subtrat rem from pairs[i].s, pairs[j].s, their values come out to be -2 instead of 0. It seems the machine skips checking if pairs[i].s == 0 or pairs[j].s == 0. I tried printing pairs[i].s - rem and pairs[j].s - rem before updating the variables, and the console read 0 in each case, but the program still got stuck in an infinite loop. Can you please help?

So you subtracted rem twice from 2 and you got -2. What’s the problem?

      int rem = min(pairs[i].s, pairs[j].s);
      pairs[i].s -= rem;
      pairs[j].s -= rem;

I subtracted rem once from each of pairs[i].s and pairs[j].s. Each of the values should therefore be 2-2 = 0. However, they are each -2.

The problem is that when i = j = 1, we skip changing pairs[i].s = pairs[j].s = 0 and advancing i and j to 2 and 0, respectively. The code gets stuck in an infinite loop.