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

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

struct Block {
  string s;
  bool overlap(Block b) {
    for (int i = 0; i < 4; i++) {
      if (s[i] == '#' && b.s[i] == '#')
        return true;
    }
    return false;
  }

  void add(Block b) {
    for (int i = 0; i < 4; i++) {
      assert(s[i] == '.' || b.s[i] == '.');
      if (b.s[i] == '#')
        s[i] = '#';
    }
  }

  bool mv(int dx, int dy) {
    if (dx == 1) {
      if (s[1] == '#' || s[3] == '#')
        return false;
      s[1] = s[0], s[3] = s[2];
      s[0] = '.', s[2] = '.';
    }
    if (dx == -1) {
      if (s[0] == '#' || s[2] == '#')
        return false;
      s[0] = s[1], s[2] = s[3];
      s[1] = '.', s[3] = '.';
    }
    if (dy == 1) {
      if (s[0] == '#' || s[1] == '#')
        return false;
      s[0] = s[2], s[1] = s[3];
      s[2] = '.', s[3] = '.';
    }
    if (dy == -1) {
      if (s[2] == '#' || s[3] == '#')
        return false;
      s[2] = s[0], s[3] = s[1];
      s[0] = '.', s[1] = '.';
    }
    return true;
  }
};

const int MAX = 25;
Block initial[MAX];
Block field[MAX];
vector<Block> b[10];
vector<Block> fall[10];
int H, N, ans;

void view() {
  for (int i = 0; i < 3; i++) {
    cout << field[i].s << endl;
  }
  cout << endl;
}

int Fall(vector<Block> t) {
  int ret = 0;
  int y = MAX - 2;
  while (y > 0) {
    if (t[0].overlap(field[y - 1]) || t[1].overlap(field[y]))
      break;
    y--;
  }
  assert(y + 1 < MAX);
  field[y].add(t[0]);
  field[y + 1].add(t[1]);
  // cerr << y << endl;
  // cerr << t[0].s << endl;
  // cerr << t[1].s << endl;

  for (int i = 0; i < MAX; i++) {
    if (field[i].s == "####") {
      ret++;
      for (int j = i + 1; j < MAX - 1; j++) {
        field[j - 1].s = field[j].s;
        field[j].s = "....";
      }
      i--;
    }
  }
  // view();
  return ret;
}

int sim() {
  int ret = 0;
  for (int i = 0; i < N; i++) {
    // cerr << i << endl;
    ret += Fall(fall[i]);
  }
  return ret;
}

void dfs(int n) {
  if (n == N) {
    for (int i = 0; i < MAX; i++) {
      field[i] = initial[i];
    }
    ans = max(ans, sim());
    return;
  }
  for (int dx = -1; dx <= 1; dx++) {
    for (int dy = -1; dy <= 1; dy++) {
      fall[n][0].s = b[n][0].s;
      fall[n][1].s = b[n][1].s;
      if (!fall[n][0].mv(dx, dy) || !fall[n][1].mv(dx, dy))
        continue;
      dfs(n + 1);
    }
  }
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  for (int i = 0; i < 10; i++) {
    b[i] = vector<Block>(2);
    fall[i] = vector<Block>(2);
  }

  while (cin >> H >> N, N) {
    for (int i = 0; i < MAX; i++) {
      initial[i].s = "....";
    }
    for (int i = 0; i < H; i++) {
      string s1, s2;
      cin >> s1 >> s2;
      initial[i].s = s1 + s2;
    }
    for (int i = 0; i < N; i++) {
      string s1, s2, s3, s4;
      cin >> s1 >> s2 >> s3 >> s4;
      b[i][0].s = s1 + s2;
      b[i][1].s = s3 + s4;
      if (b[i][0].s == "....") {
        swap(b[i][0].s, b[i][1].s);
      }
    }

    ans = 0;
    dfs(0);
    cout << ans << endl;
  }
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

struct Block {
  string s;
  bool overlap(Block b) {
    for (int i = 0; i < 4; i++) {
      if (s[i] == '#' && b.s[i] == '#')
        return true;
    }
    return false;
  }

  void add(Block b) {
    for (int i = 0; i < 4; i++) {
      assert(s[i] == '.' || b.s[i] == '.');
      if (b.s[i] == '#')
        s[i] = '#';
    }
  }

  bool mv(int dx, int dy) {
    if (dx == 1) {
      if (s[1] == '#' || s[3] == '#')
        return false;
      s[1] = s[0], s[3] = s[2];
      s[0] = '.', s[2] = '.';
    }
    if (dx == -1) {
      if (s[0] == '#' || s[2] == '#')
        return false;
      s[0] = s[1], s[2] = s[3];
      s[1] = '.', s[3] = '.';
    }
    if (dy == 1) {
      if (s[0] == '#' || s[1] == '#')
        return false;
      s[0] = s[2], s[1] = s[3];
      s[2] = '.', s[3] = '.';
    }
    if (dy == -1) {
      if (s[2] == '#' || s[3] == '#')
        return false;
      s[2] = s[0], s[3] = s[1];
      s[0] = '.', s[1] = '.';
    }
    return true;
  }
};

const int MAX = 25;
Block initial[MAX];
Block field[MAX];
vector<Block> b[10];
vector<Block> fall[10];
int H, N, ans;

void view() {
  for (int i = 0; i < 3; i++) {
    cout << field[i].s << endl;
  }
  cout << endl;
}

int Fall(vector<Block> t) {
  int ret = 0;
  int y = MAX - 2;
  while (y > 0) {
    if (t[0].overlap(field[y - 1]) || t[1].overlap(field[y]))
      break;
    y--;
  }
  assert(y + 1 < MAX);
  field[y].add(t[0]);
  field[y + 1].add(t[1]);
  // cerr << y << endl;
  // cerr << t[0].s << endl;
  // cerr << t[1].s << endl;

  for (int i = 0; i < MAX; i++) {
    if (field[i].s == "####") {
      ret++;
      for (int j = i + 1; j < MAX - 1; j++) {
        field[j - 1].s = field[j].s;
        field[j].s = "....";
        i--;
      }
    }
  }
  // view();
  return ret;
}

int sim() {
  int ret = 0;
  for (int i = 0; i < N; i++) {
    // cerr << i << endl;
    ret += Fall(fall[i]);
  }
  return ret;
}

void dfs(int n) {
  if (n == N) {
    for (int i = 0; i < MAX; i++) {
      field[i] = initial[i];
    }
    ans = max(ans, sim());
    return;
  }
  for (int dx = -1; dx <= 1; dx++) {
    for (int dy = -1; dy <= 1; dy++) {
      fall[n][0].s = b[n][0].s;
      fall[n][1].s = b[n][1].s;
      if (!fall[n][0].mv(dx, dy) || !fall[n][1].mv(dx, dy))
        continue;
      dfs(n + 1);
    }
  }
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  for (int i = 0; i < 10; i++) {
    b[i] = vector<Block>(2);
    fall[i] = vector<Block>(2);
  }

  while (cin >> H >> N, N) {
    for (int i = 0; i < MAX; i++) {
      initial[i].s = "....";
    }
    for (int i = 0; i < H; i++) {
      string s1, s2;
      cin >> s1 >> s2;
      initial[i].s = s1 + s2;
    }
    for (int i = 0; i < N; i++) {
      string s1, s2, s3, s4;
      cin >> s1 >> s2 >> s3 >> s4;
      b[i][0].s = s1 + s2;
      b[i][1].s = s3 + s4;
      if (b[i][0].s == "....") {
        swap(b[i][0].s, b[i][1].s);
      }
    }

    ans = 0;
    dfs(0);
    cout << ans << endl;
  }
}