Problem p00698 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cassert>
#include <cstdlib>
#include <deque>
#include <iostream>
#include <sstream>
#include <vector>
#define MAX 1000
#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define inf (1 << 29)
using namespace std;
typedef pair<int, int> P;
int h, w;
int G[MAX][MAX];
int A[MAX][2]; // 0->r, 1->c
P B[MAX][2];
int C[MAX][2];
int D[MAX][2];

void printA() {
  cout << "printA---" << endl;
  rep(i, w) cout << A[i][0] << " ";
  cout << endl;
  rep(i, h) cout << A[i][1] << " ";
  cout << endl;
  cout << endl;
}

void printB() {
  cout << "printB---" << endl;
  rep(i, w) cout << B[i][0].first << "," << B[i][0].second << " ";
  cout << endl;
  rep(i, h) cout << B[i][1].first << "," << B[1][i].second << " ";
  cout << endl;
  cout << endl;
}

void printC() {
  cout << "printC---" << endl;
  rep(i, w) cout << C[i][0] << " ";
  cout << endl;
  rep(i, h) cout << C[i][1] << " ";
  cout << endl;
  cout << endl;
}

void printD() {
  cout << "printD---" << endl;
  rep(i, w) cout << D[i][0] << " ";
  cout << endl;
  rep(i, h) cout << D[i][1] << " ";
  cout << endl;
}

P Bsearch(int a, int b) {
  int Size = (b == 0 ? w : h);
  for (int i = 0; i < Size; i++) {
    if (b == 0) {
      if (G[i][a] == -inf)
        return P(a, i);
    } else {
      if (G[a][i] == -inf)
        return P(i, a);
    }
  }
}

int main() {
  int blank = false;
  while (true) {
    cin >> h;
    if (!h)
      break;
    cin >> w;
    rep(i, MAX) rep(j, 2) A[i][j] = C[i][j] = 0, B[i][j] = P(-inf, -inf);

    vector<P> ans;
    int hatena = 0;
    rep(i, h) {
      rep(j, w) {
        string input;
        cin >> input;
        if (input[0] == '?') {
          G[i][j] = -inf;
          A[j][0]++;
          B[j][0] = P(j, i);
          A[i][1]++;
          B[i][1] = P(j, i);
          ans.push_back(P(j, i));
        } else {
          G[i][j] = (atoi)(input.c_str());
          C[j][0] += G[i][j];
          C[i][1] += G[i][j];
        }
      }
      cin >> D[i][1];
    }
    rep(i, w + 1) cin >> D[i][0];

    // printA();
    // printB();
    // printC();
    // printD();
    // return 0;
    bool Fin = true;
    bool found = false;

    while (true) {
      // cout << "phase !" << endl;
      // printA();
      // printB();
      // printC();
      // printD();
      Fin = true;
      found = false;
      rep(i, w) {
        if (A[i][0] >= 1)
          Fin = false;
        if (A[i][0] == 1) {
          // cout << "erase! " << B[i][0].first << "," << B[i][0].second <<
          // endl;
          found = true;
          int value = D[i][0] - C[i][0];
          P p = Bsearch(i, 0);
          C[p.first][0] += value;
          C[p.second][1] += value;
          A[p.first][0]--;
          A[p.second][1]--;
          assert(G[p.second][p.first] == -inf);
          G[p.second][p.first] = value;
        }
      }
      rep(i, h) {
        if (A[i][1] >= 1)
          Fin = false;
        if (A[i][1] == 1) {
          // cout << "erase! " << B[i][1].first << "," << B[i][1].second <<
          // endl;
          found = true;
          int value = D[i][1] - C[i][1];
          P p = Bsearch(i, 1);
          C[p.first][0] += value;
          C[p.second][1] += value;
          A[p.first][0]--;
          A[p.second][1]--;
          assert(G[p.second][p.first] == -inf);
          G[p.second][p.first] = value;
        }
      }

      if (!Fin && !found)
        break;
      if (Fin)
        break;
    }
    if (!blank)
      blank = true;
    else
      cout << endl;
    if (!Fin && !found)
      cout << "NO" << endl;
    else {
      rep(i, ans.size()) cout << G[ans[i].second][ans[i].first] << endl;
    }
  }
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cassert>
#include <cstdlib>
#include <deque>
#include <iostream>
#include <sstream>
#include <vector>
#define MAX 1000
#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define inf (1 << 29)
using namespace std;
typedef pair<int, int> P;
int h, w;
int G[MAX][MAX];
int A[MAX][2]; // 0->r, 1->c
P B[MAX][2];
int C[MAX][2];
int D[MAX][2];

void printA() {
  cout << "printA---" << endl;
  rep(i, w) cout << A[i][0] << " ";
  cout << endl;
  rep(i, h) cout << A[i][1] << " ";
  cout << endl;
  cout << endl;
}

void printB() {
  cout << "printB---" << endl;
  rep(i, w) cout << B[i][0].first << "," << B[i][0].second << " ";
  cout << endl;
  rep(i, h) cout << B[i][1].first << "," << B[1][i].second << " ";
  cout << endl;
  cout << endl;
}

void printC() {
  cout << "printC---" << endl;
  rep(i, w) cout << C[i][0] << " ";
  cout << endl;
  rep(i, h) cout << C[i][1] << " ";
  cout << endl;
  cout << endl;
}

void printD() {
  cout << "printD---" << endl;
  rep(i, w) cout << D[i][0] << " ";
  cout << endl;
  rep(i, h) cout << D[i][1] << " ";
  cout << endl;
}

P Bsearch(int a, int b) {
  int Size = (b == 0 ? h : w);
  for (int i = 0; i < Size; i++) {
    if (b == 0) {
      if (G[i][a] == -inf)
        return P(a, i);
    } else {
      if (G[a][i] == -inf)
        return P(i, a);
    }
  }
}

int main() {
  int blank = false;
  while (true) {
    cin >> h;
    if (!h)
      break;
    cin >> w;
    rep(i, MAX) rep(j, 2) A[i][j] = C[i][j] = 0, B[i][j] = P(-inf, -inf);

    vector<P> ans;
    int hatena = 0;
    rep(i, h) {
      rep(j, w) {
        string input;
        cin >> input;
        if (input[0] == '?') {
          G[i][j] = -inf;
          A[j][0]++;
          B[j][0] = P(j, i);
          A[i][1]++;
          B[i][1] = P(j, i);
          ans.push_back(P(j, i));
        } else {
          G[i][j] = (atoi)(input.c_str());
          C[j][0] += G[i][j];
          C[i][1] += G[i][j];
        }
      }
      cin >> D[i][1];
    }
    rep(i, w + 1) cin >> D[i][0];

    // printA();
    // printB();
    // printC();
    // printD();
    // return 0;
    bool Fin = true;
    bool found = false;

    while (true) {
      // cout << "phase !" << endl;
      // printA();
      // printB();
      // printC();
      // printD();
      Fin = true;
      found = false;
      rep(i, w) {
        if (A[i][0] >= 1)
          Fin = false;
        if (A[i][0] == 1) {
          // cout << "erase! " << B[i][0].first << "," << B[i][0].second <<
          // endl;
          found = true;
          int value = D[i][0] - C[i][0];
          P p = Bsearch(i, 0);
          C[p.first][0] += value;
          C[p.second][1] += value;
          A[p.first][0]--;
          A[p.second][1]--;
          assert(G[p.second][p.first] == -inf);
          G[p.second][p.first] = value;
        }
      }
      rep(i, h) {
        if (A[i][1] >= 1)
          Fin = false;
        if (A[i][1] == 1) {
          // cout << "erase! " << B[i][1].first << "," << B[i][1].second <<
          // endl;
          found = true;
          int value = D[i][1] - C[i][1];
          P p = Bsearch(i, 1);
          C[p.first][0] += value;
          C[p.second][1] += value;
          A[p.first][0]--;
          A[p.second][1]--;
          assert(G[p.second][p.first] == -inf);
          G[p.second][p.first] = value;
        }
      }

      if (!Fin && !found)
        break;
      if (Fin)
        break;
    }
    if (!blank)
      blank = true;
    else
      cout << endl;
    if (!Fin && !found)
      cout << "NO" << endl;
    else {
      rep(i, ans.size()) cout << G[ans[i].second][ans[i].first] << endl;
    }
  }
  return 0;
}