Problem p00091 (C++) — buggy submission, verdict: Runtime Error

#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES

#include <algorithm>
#include <cmath>
#include <ctime>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string>

using namespace std;
typedef long long int lint;

class Drop {
public:
  int x;
  int y;
  int size;
  Drop() {
    x = 0;
    y = 0;
    size = 0;
  }
  Drop(int x, int y, int size) {
    this->x = x;
    this->y = y;
    this->size = size;
  }
};

class Point {
public:
  int x;
  int y;
  Point() {
    x = 0;
    y = 0;
  }
  Point(int x, int y) {
    this->x = x;
    this->y = y;
  }
};

int N;
int m[10][10];
int sum;
stack<Drop> drops;
Point p;
bool solved;

// 染料を取り除く
void popDrop(int x, int y, int size) {
  int dx, dy;
  if (size == 3) {
    for (dy = -1; dy <= 1; dy++) {
      for (dx = -1; dx <= 1; dx++) {
        m[y + dy][x + dx]--;
      }
    }
    m[y - 2][x]--;
    m[y][x - 2]--;
    m[y][x + 2]--;
    m[y + 2][x]--;
    return;
  }
  if (size == 2) {
    for (dy = -1; dy <= 1; dy++) {
      for (dx = -1; dx <= 1; dx++) {
        m[y + dy][x + dx]--;
      }
    }
    return;
  }
  if (size == 1) {
    m[y - 1][x]--;
    m[y][x - 1]--;
    m[y][x]--;
    m[y][x + 1]--;
    m[y + 1][x]--;
  }
}

// 染料を垂らす
void pushDrop(int x, int y, int size) {
  int dx, dy;
  if (size == 3) {
    for (dy = -1; dy <= 1; dy++) {
      for (dx = -1; dx <= 1; dx++) {
        m[y + dy][x + dx]++;
      }
    }
    m[y - 2][x]++;
    m[y][x - 2]++;
    m[y][x + 2]++;
    m[y + 2][x]++;
    return;
  }
  if (size == 2) {
    for (dy = -1; dy <= 1; dy++) {
      for (dx = -1; dx <= 1; dx++) {
        m[y + dy][x + dx]++;
      }
    }
    return;
  }
  if (size == 1) {
    m[y - 1][x]++;
    m[y][x - 1]++;
    m[y][x]++;
    m[y][x + 1]++;
    m[y + 1][x]++;
  }
}

bool judge(int x, int y, int size) {
  int dx, dy;
  if (size == 3) {
    if (x <= 1 || x >= 8 || y <= 1 || y >= 8)
      return false;
    for (dy = -1; dy <= 1; dy++) {
      for (dx = -1; dx <= 1; dx++) {
        if (m[y + dy][x + dx] == 0)
          return false;
      }
    }
    if (m[y - 2][x] == 0)
      return false;
    if (m[y][x - 2] == 0)
      return false;
    if (m[y][x + 2] == 0)
      return false;
    if (m[y + 2][x] == 0)
      return false;
    return true;
  }
  if (size == 2) {
    if (x <= 0 || x >= 9 || y <= 0 || y >= 9)
      return false;
    for (dy = -1; dy <= 1; dy++) {
      for (dx = -1; dx <= 1; dx++) {
        if (m[y + dy][x + dx] == 0)
          return false;
      }
    }
    return true;
  }
  if (size == 1) {
    if (m[y - 1][x] == 0)
      return false;
    if (m[y][x - 1] == 0)
      return false;
    if (m[y][x] == 0)
      return false;
    if (m[y][x + 1] == 0)
      return false;
    if (m[y + 1][x] == 0)
      return false;
    return true;
  }
}

void nextPoint() {
  if (p.x == 9) {
    p.x = 0;
    p.y++;
  } else {
    p.x++;
  }
}

void solve() {
  // m[p.y][p.x] != 0
  // size = 3 として取り除く
  // size = 2 として取り除く
  // size = 1 として取り除く
  // できなければエラー、バックトラック
  // m[p.y][p.x] == 0
  // 次の座標へ
  if (sum == 0) {
    while (!drops.empty()) {
      cout << drops.top().x << " " << drops.top().y << " " << drops.top().size
           << endl;
      drops.pop();
    }
    solved = true;
    return;
  }
  if (N == 0)
    return;

  while (true) {
    if (m[p.y][p.x] != 0) {
      if (judge(p.x, p.y + 2, 3)) {
        popDrop(p.x, p.y + 2, 3);
        N--;
        sum -= 13;
        drops.push(Drop(p.x, p.y + 2, 3));
        solve();
        if (solved)
          return;
        p.x = drops.top().x;
        p.y = drops.top().y - 2;
        drops.pop();
        sum += 13;
        N++;
        pushDrop(p.x, p.y + 2, 3);
      }
      if (judge(p.x + 1, p.y + 1, 2)) {
        popDrop(p.x + 1, p.y + 1, 2);
        N--;
        sum -= 9;
        drops.push(Drop(p.x + 1, p.y + 1, 2));
        solve();
        if (solved)
          return;
        p.x = drops.top().x - 1;
        p.y = drops.top().y - 1;
        drops.pop();
        sum += 9;
        N++;
        pushDrop(p.x + 1, p.y + 1, 2);
      }
      if (judge(p.x, p.y + 1, 1)) {
        popDrop(p.x, p.y + 1, 1);
        N--;
        sum -= 5;
        drops.push(Drop(p.x, p.y + 1, 1));
        solve();
        if (solved)
          return;
        p.x = drops.top().x;
        p.y = drops.top().y - 1;
        drops.pop();
        sum += 5;
        N++;
        pushDrop(p.x, p.y + 1, 1);
      }
      return;
    }
    if (m[p.y][p.x] == 0) {
      nextPoint();
    }
  }
}

int main() {
  cin >> N;
  sum = 0;
  for (int y = 0; y < 10; y++) {
    for (int x = 0; x < 10; x++) {
      cin >> m[y][x];
      sum += m[y][x];
    }
  }

  solved = false;
  solve();

  return 0;
}

Error: 1

Fixed submission:

#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES

#include <algorithm>
#include <cmath>
#include <ctime>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string>

using namespace std;
typedef long long int lint;

class Drop {
public:
  int x;
  int y;
  int size;
  Drop() {
    x = 0;
    y = 0;
    size = 0;
  }
  Drop(int x, int y, int size) {
    this->x = x;
    this->y = y;
    this->size = size;
  }
};

class Point {
public:
  int x;
  int y;
  Point() {
    x = 0;
    y = 0;
  }
  Point(int x, int y) {
    this->x = x;
    this->y = y;
  }
};

int N;
int m[10][10];
int sum;
stack<Drop> drops;
Point p;

// 染料を取り除く
void popDrop(int x, int y, int size) {
  int dx, dy;
  if (size == 3) {
    for (dy = -1; dy <= 1; dy++) {
      for (dx = -1; dx <= 1; dx++) {
        m[y + dy][x + dx]--;
      }
    }
    m[y - 2][x]--;
    m[y][x - 2]--;
    m[y][x + 2]--;
    m[y + 2][x]--;
    return;
  }
  if (size == 2) {
    for (dy = -1; dy <= 1; dy++) {
      for (dx = -1; dx <= 1; dx++) {
        m[y + dy][x + dx]--;
      }
    }
    return;
  }
  if (size == 1) {
    m[y - 1][x]--;
    m[y][x - 1]--;
    m[y][x]--;
    m[y][x + 1]--;
    m[y + 1][x]--;
  }
}

// 染料を垂らす
void pushDrop(int x, int y, int size) {
  int dx, dy;
  if (size == 3) {
    for (dy = -1; dy <= 1; dy++) {
      for (dx = -1; dx <= 1; dx++) {
        m[y + dy][x + dx]++;
      }
    }
    m[y - 2][x]++;
    m[y][x - 2]++;
    m[y][x + 2]++;
    m[y + 2][x]++;
    return;
  }
  if (size == 2) {
    for (dy = -1; dy <= 1; dy++) {
      for (dx = -1; dx <= 1; dx++) {
        m[y + dy][x + dx]++;
      }
    }
    return;
  }
  if (size == 1) {
    m[y - 1][x]++;
    m[y][x - 1]++;
    m[y][x]++;
    m[y][x + 1]++;
    m[y + 1][x]++;
  }
}

bool judge(int x, int y, int size) {
  int dx, dy;
  if (size == 3) {
    if (x <= 1 || x >= 8 || y <= 1 || y >= 8)
      return false;
    for (dy = -1; dy <= 1; dy++) {
      for (dx = -1; dx <= 1; dx++) {
        if (m[y + dy][x + dx] == 0)
          return false;
      }
    }
    if (m[y - 2][x] == 0)
      return false;
    if (m[y][x - 2] == 0)
      return false;
    if (m[y][x + 2] == 0)
      return false;
    if (m[y + 2][x] == 0)
      return false;
    return true;
  }
  if (size == 2) {
    if (x <= 0 || x >= 9 || y <= 0 || y >= 9)
      return false;
    for (dy = -1; dy <= 1; dy++) {
      for (dx = -1; dx <= 1; dx++) {
        if (m[y + dy][x + dx] == 0)
          return false;
      }
    }
    return true;
  }
  if (size == 1) {
    if (m[y - 1][x] == 0)
      return false;
    if (m[y][x - 1] == 0)
      return false;
    if (m[y][x] == 0)
      return false;
    if (m[y][x + 1] == 0)
      return false;
    if (m[y + 1][x] == 0)
      return false;
    return true;
  }
}

void nextPoint() {
  if (p.x == 9) {
    p.x = 0;
    p.y++;
  } else {
    p.x++;
  }
}

void solve() {
  // m[p.y][p.x] != 0
  // size = 3 として取り除く
  // size = 2 として取り除く
  // size = 1 として取り除く
  // できなければエラー、バックトラック
  // m[p.y][p.x] == 0
  // 次の座標へ
  if (sum == 0) {
    while (!drops.empty()) {
      cout << drops.top().x << " " << drops.top().y << " " << drops.top().size
           << endl;
      drops.pop();
    }
    exit(1);
  }
  if (N == 0)
    return;

  while (true) {
    if (m[p.y][p.x] != 0) {
      if (judge(p.x, p.y + 2, 3)) {
        popDrop(p.x, p.y + 2, 3);
        N--;
        sum -= 13;
        drops.push(Drop(p.x, p.y + 2, 3));
        solve();
        p.x = drops.top().x;
        p.y = drops.top().y - 2;
        drops.pop();
        sum += 13;
        N++;
        pushDrop(p.x, p.y + 2, 3);
      }
      if (judge(p.x + 1, p.y + 1, 2)) {
        popDrop(p.x + 1, p.y + 1, 2);
        N--;
        sum -= 9;
        drops.push(Drop(p.x + 1, p.y + 1, 2));
        solve();
        p.x = drops.top().x - 1;
        p.y = drops.top().y - 1;
        drops.pop();
        sum += 9;
        N++;
        pushDrop(p.x + 1, p.y + 1, 2);
      }
      if (judge(p.x, p.y + 1, 1)) {
        popDrop(p.x, p.y + 1, 1);
        N--;
        sum -= 5;
        drops.push(Drop(p.x, p.y + 1, 1));
        solve();
        p.x = drops.top().x;
        p.y = drops.top().y - 1;
        drops.pop();
        sum += 5;
        N++;
        pushDrop(p.x, p.y + 1, 1);
      }
      return;
    }
    if (m[p.y][p.x] == 0) {
      nextPoint();
    }
  }
}

int main() {
  cin >> N;
  sum = 0;
  for (int y = 0; y < 10; y++) {
    for (int x = 0; x < 10; x++) {
      cin >> m[y][x];
      sum += m[y][x];
    }
  }

  solve();

  return 0;
}