Problem p00213 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef istringstream ISS;
typedef ostringstream OSS;
typedef vector<string> VS;
typedef int INT;
typedef vector<INT> VI;
typedef vector<VI> VVI;
typedef pair<INT, INT> II;
typedef vector<II> VII;

template <class T> ostream &operator<<(ostream &os, vector<T> v) {
  for (typename vector<T>::iterator it_i = v.begin(); it_i != v.end(); ++it_i) {
    os << *it_i << ", ";
  }
  return os;
}

const int WH_SIZE = 11;
const int SIZE = 16;
int w, h;
int n;
int K[SIZE];
int S[WH_SIZE][WH_SIZE];
II T[11];
VVI M;
VVI A;
int cnt;

void input() {
  for (int i = 0; i < n; ++i) {
    int b;
    cin >> b;
    b--;
    cin >> K[b];
  }
  for (int i = 0; i < h; ++i) {
    for (int j = 0; j < w; ++j) {
      int b;
      cin >> b;
      S[i][j] = b;
      if (b > 0) {
        b--;
        T[b] = II(i, j);
      }
    }
  }
}

void output() {
  for (int i = 0; i < h; ++i) {
    for (int j = 0; j < w; ++j) {
      cout << A[i][j];
      if (j + 1 < w)
        cout << " ";
    }
    cout << endl;
  }
}

bool canPut(int k, int r0, int c0, int w0, int h0) {
  for (int i = 0; i < h0; ++i) {
    for (int j = 0; j < w0; ++j) {
      int r1 = r0 + i;
      int c1 = c0 + j;
      if (S[r1][c1] != k && S[r1][c1] != 0)
        return false;
      if (M[r1][c1] != 0)
        return false;
    }
  }
  return true;
}

void put(int k, int r0, int c0, int w0, int h0) {
  for (int i = 0; i < h0; ++i) {
    for (int j = 0; j < w0; ++j) {
      int r1 = r0 + i;
      int c1 = c0 + j;
      M[r1][c1] = k;
    }
  }
}

void solve(int depth) {
  if (depth >= n) {
    A = M;
    cnt++;
    return;
  }

  int r = T[depth].first;
  int c = T[depth].second;
  int k = K[depth];
  for (int w0 = 1; w0 <= w; ++w0) {
    if (k % w0 != 0)
      continue;
    int h0 = k / w0;
    for (int r0 = max(0, r - h0 + 1); r0 + h0 - 1 < h; ++r0) {
      for (int c0 = max(0, c - w0 + 1); c0 + w0 - 1 < w; ++c0) {
        if (!(r0 <= r && r <= r0 + h0 - 1 && c0 <= c && c <= c0 + w0 - 1))
          continue;
        if (!canPut(depth + 1, r0, c0, w0, h0))
          continue;
        put(depth + 1, r0, c0, w0, h0);
        solve(depth + 1);
        if (cnt >= 2)
          return;
        put(0, r0, c0, w0, h0);
      }
    }
  }

  return;
}

int main() {
  while (cin >> w >> h >> n) {
    if (w == 0 && h == 0 && n == 0)
      break;
    M = VVI(h, VI(w, 0));
    input();
    cnt = 0;
    solve(0);
    if (cnt == 0 || cnt == 2) {
      cout << "NA" << endl;
    } else {
      output();
    }
  }
  return 0;
}

Fixed submission:
#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef istringstream ISS;
typedef ostringstream OSS;
typedef vector<string> VS;
typedef int INT;
typedef vector<INT> VI;
typedef vector<VI> VVI;
typedef pair<INT, INT> II;
typedef vector<II> VII;

template <class T> ostream &operator<<(ostream &os, vector<T> v) {
  for (typename vector<T>::iterator it_i = v.begin(); it_i != v.end(); ++it_i) {
    os << *it_i << ", ";
  }
  return os;
}

const int WH_SIZE = 11;
const int SIZE = 16;
int w, h;
int n;
int K[SIZE * 2];
int S[WH_SIZE * 2][WH_SIZE * 2];
II T[11 * 2];
VVI M;
VVI A;
int cnt;

void input() {
  for (int i = 0; i < n; ++i) {
    int b;
    cin >> b;
    b--;
    cin >> K[b];
  }
  for (int i = 0; i < h; ++i) {
    for (int j = 0; j < w; ++j) {
      int b;
      cin >> b;
      S[i][j] = b;
      if (b > 0) {
        b--;
        T[b] = II(i, j);
      }
    }
  }
}

void output() {
  for (int i = 0; i < h; ++i) {
    for (int j = 0; j < w; ++j) {
      cout << A[i][j];
      if (j + 1 < w)
        cout << " ";
    }
    cout << endl;
  }
}

bool canPut(int k, int r0, int c0, int w0, int h0) {
  for (int i = 0; i < h0; ++i) {
    for (int j = 0; j < w0; ++j) {
      int r1 = r0 + i;
      int c1 = c0 + j;
      if (S[r1][c1] != k && S[r1][c1] != 0)
        return false;
      if (M[r1][c1] != 0)
        return false;
    }
  }
  return true;
}

void put(int k, int r0, int c0, int w0, int h0) {
  for (int i = 0; i < h0; ++i) {
    for (int j = 0; j < w0; ++j) {
      int r1 = r0 + i;
      int c1 = c0 + j;
      M[r1][c1] = k;
    }
  }
}

void solve(int depth) {
  if (depth >= n) {
    A = M;
    cnt++;
    return;
  }

  int r = T[depth].first;
  int c = T[depth].second;
  int k = K[depth];
  for (int w0 = 1; w0 <= w; ++w0) {
    if (k % w0 != 0)
      continue;
    int h0 = k / w0;
    for (int r0 = max(0, r - h0 + 1); r0 + h0 - 1 < h; ++r0) {
      for (int c0 = max(0, c - w0 + 1); c0 + w0 - 1 < w; ++c0) {
        if (!(r0 <= r && r <= r0 + h0 - 1 && c0 <= c && c <= c0 + w0 - 1))
          continue;
        if (!canPut(depth + 1, r0, c0, w0, h0))
          continue;
        put(depth + 1, r0, c0, w0, h0);
        solve(depth + 1);
        if (cnt >= 2)
          return;
        put(0, r0, c0, w0, h0);
      }
    }
  }

  return;
}

int main() {
  while (cin >> w >> h >> n) {
    if (w == 0 && h == 0 && n == 0)
      break;
    M = VVI(h, VI(w, 0));
    input();
    cnt = 0;
    solve(0);
    if (cnt == 0 || cnt == 2) {
      cout << "NA" << endl;
    } else {
      output();
    }
  }
  return 0;
}