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

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <map>
#include <set>
using namespace std;
typedef long long int64;
typedef pair<int64, int64> pll;

const int MAX_N = 100000;

int ops[MAX_N];

bool dp[MAX_N + 1][3][3][3];
int prv[MAX_N + 1][3][3][3];
int inc[MAX_N];

int stra(int64 &A, int64 &B, int64 &C, int op) {
  if (op == 2) {
    if (A >= B) {
      --A, ++B;
      return 1;
    } else {
      ++A, --B;
      return 0;
    }
  }
  if (op == 1) {
    if (A >= C) {
      --A, ++C;
      return 2;
    } else {
      ++A, --C;
      return 0;
    }
  }
  if (op == 0) {
    if (B >= C) {
      --B, ++C;
      return 2;
    } else {
      ++B, --C;
      return 1;
    }
  }
  assert(false);
  return -1;
}

bool solve(int N, int64 A, int64 B, int64 C) {
  if (A + B + C >= 3) {
    // A is rich
    if (B == 0 && C == 0)
      if (ops[0] == 0)
        return false;
    // B is rich
    if (A == 0 && C == 0)
      if (ops[0] == 1)
        return false;
    // C is rich
    if (A == 0 && B == 0)
      if (ops[0] == 2)
        return false;

    for (int i = 0; i < N; ++i)
      inc[i] = stra(A, B, C, ops[i]);
    return true;
  }

  if (A + B + C <= 2) {
    dp[0][A][B][C] = 1;
    for (int i = 0; i < N; ++i) {
      for (int nA = 0; nA <= 2; ++nA)
        for (int nB = 0; nB <= 2; ++nB)
          for (int nC = 0; nC <= 2; ++nC) {
            if (dp[i][nA][nB][nC] == false)
              continue;

            if (ops[i] == 0) {
              if (nB - 1 >= 0) {
                dp[i + 1][nA][nB - 1][nC + 1] = true;
                prv[i + 1][nA][nB - 1][nC + 1] = 2;
              }
              if (nC - 1 >= 0) {
                dp[i + 1][nA][nB + 1][nC - 1] = true;
                prv[i + 1][nA][nB + 1][nC - 1] = 1;
              }
            }
            if (ops[i] == 1) {
              if (nA - 1 >= 0) {
                dp[i + 1][nA - 1][nB][nC + 1] = true;
                prv[i + 1][nA - 1][nB][nC + 1] = 2;
              }
              if (nC - 1 >= 0) {
                dp[i + 1][nA + 1][nB][nC - 1] = true;
                prv[i + 1][nA + 1][nB][nC - 1] = 0;
              }
            }
            if (ops[i] == 2) {
              if (nA - 1 >= 0) {
                dp[i + 1][nA - 1][nB + 1][nC] = true;
                prv[i + 1][nA - 1][nB + 1][nC] = 1;
              }
              if (nB - 1 >= 0) {
                dp[i + 1][nA + 1][nB - 1][nC] = true;
                prv[i + 1][nA + 1][nB - 1][nC] = 0;
              }
            }
          }
    }
    bool ret = false;
    int i, j, k;
    for (int nA = 0; nA <= 2; ++nA)
      for (int nB = 0; nB <= 2; ++nB)
        for (int nC = 0; nC <= 2; ++nC) {
          if (dp[N][nA][nB][nC]) {
            i = nA, j = nB, k = nC;
            ret = true;
          }
        }

    if (ret == false)
      return false;

    for (int t = N; t > 0; --t) {
      int m = prv[t][i][j][k];
      inc[t - 1] = m;
      if (m == 0) {
        --i;
        if (ops[t - 1] == 1)
          ++k;
        if (ops[t - 1] == 2)
          ++j;
      }
      if (m == 1) {
        --j;
        if (ops[t - 1] == 0)
          ++k;
        if (ops[t - 1] == 2)
          ++i;
      }

      if (m == 2) {
        --k;
        if (ops[t - 1] == 0)
          ++j;
        if (ops[t - 1] == 1)
          ++i;
      }
    }
    return true;
  }
  assert(false);
  return 0;
}
char buffer[100];
int main() {
  int N, A, B, C;
  scanf("%d%d%d%d", &N, &A, &B, &C);
  for (int i = 0; i < N; ++i) {
    scanf(" %s", buffer);
    if (buffer[0] != 'A' && buffer[1] != 'A')
      ops[i] = 0;
    if (buffer[0] != 'B' && buffer[1] != 'B')
      ops[i] = 1;
    if (buffer[0] != 'C' && buffer[1] != 'C')
      ops[i] = 2;
  }
  if (solve(N, A, B, C)) {
    puts("Yes");
    for (int i = 0; i < N; ++i)
      printf("%c\\n", "ABC"[inc[i]]);
  } else {
    puts("No");
  }
}

Error: -6
4af92ec6-f1c7-4a9a-8602-5490c61e201c.out: /home/alex/Documents/bug-detection/input/Project_CodeNet/data/p02692/C++/s955461286.cpp:54: bool solve(int, int64, int64, int64): Assertion `false' failed.


Fixed submission:

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <map>
#include <set>
using namespace std;
typedef long long int64;
typedef pair<int64, int64> pll;

const int MAX_N = 100000;

int ops[MAX_N];

bool dp[MAX_N + 1][3][3][3];
int prv[MAX_N + 1][3][3][3];
int inc[MAX_N];

int stra(int64 &A, int64 &B, int64 &C, int op) {
  if (op == 2) {
    if (A >= B) {
      --A, ++B;
      return 1;
    } else {
      ++A, --B;
      return 0;
    }
  }
  if (op == 1) {
    if (A >= C) {
      --A, ++C;
      return 2;
    } else {
      ++A, --C;
      return 0;
    }
  }
  if (op == 0) {
    if (B >= C) {
      --B, ++C;
      return 2;
    } else {
      ++B, --C;
      return 1;
    }
  }
  assert(false);
  return -1;
}

bool solve(int N, int64 A, int64 B, int64 C) {
  if (A + B + C >= 3) {
    assert(false);

    // A is rich
    if (B == 0 && C == 0)
      if (ops[0] == 0)
        return false;
    // B is rich
    if (A == 0 && C == 0)
      if (ops[0] == 1)
        return false;
    // C is rich
    if (A == 0 && B == 0)
      if (ops[0] == 2)
        return false;

    for (int i = 0; i < N; ++i)
      inc[i] = stra(A, B, C, ops[i]);
    return true;
  }

  if (A + B + C <= 2) {
    dp[0][A][B][C] = 1;
    for (int i = 0; i < N; ++i) {
      for (int nA = 0; nA <= 2; ++nA)
        for (int nB = 0; nB <= 2; ++nB)
          for (int nC = 0; nC <= 2; ++nC) {
            if (dp[i][nA][nB][nC] == false)
              continue;

            if (ops[i] == 0) {
              if (nB - 1 >= 0) {
                dp[i][nA][nB - 1][nC + 1] = true;
                prv[i][nA][nB - 1][nC + 1] = 2;
              }
              if (nC - 1 >= 0) {
                dp[i][nA][nB + 1][nC - 1] = true;
                prv[i][nA][nB + 1][nC - 1] = 1;
              }
            }
            if (ops[i] == 1) {
              if (nA - 1 >= 0) {
                dp[i][nA - 1][nB][nC + 1] = true;
                prv[i][nA - 1][nB][nC + 1] = 2;
              }
              if (nC - 1 >= 0) {
                dp[i][nA + 1][nB][nC - 1] = true;
                prv[i][nA + 1][nB][nC - 1] = 0;
              }
            }
            if (ops[i] == 2) {
              if (nA - 1 >= 0) {
                dp[i][nA - 1][nB + 1][nC] = true;
                prv[i][nA - 1][nB + 1][nC] = 1;
              }
              if (nB - 1 >= 0) {
                dp[i][nA + 1][nB - 1][nC] = true;
                prv[i][nA + 1][nB - 1][nC] = 0;
              }
            }
          }
    }
    bool ret = false;
    int i, j, k;
    for (int nA = 0; nA <= 2; ++nA)
      for (int nB = 0; nB <= 2; ++nB)
        for (int nC = 0; nC <= 2; ++nC) {
          if (dp[N][nA][nB][nC]) {
            i = nA, j = nB, k = nC;
            ret = true;
          }
        }

    if (ret == false)
      return false;

    for (int t = N; t > 0; --t) {
      int m = prv[t][i][j][k];
      inc[t - 1] = m;
      if (m == 0) {
        ++i;
        if (ops[t - 1] == 1)
          --k;
        if (ops[t - 1] == 2)
          --j;
      }
      if (m == 1) {
        ++j;
        if (ops[t - 1] == 0)
          --k;
        if (ops[t - 1] == 2)
          --i;
      }

      if (m == 2) {
        ++k;
        if (ops[t - 1] == 0)
          --j;
        if (ops[t - 1] == 1)
          --i;
      }
    }
    return true;
  }
  assert(false);
  return 0;
}
char buffer[100];
int main() {
  int N, A, B, C;
  scanf("%d%d%d%d", &N, &A, &B, &C);
  for (int i = 0; i < N; ++i) {
    scanf(" %s", buffer);
    if (buffer[0] != 'A' && buffer[1] != 'A')
      ops[i] = 0;
    if (buffer[0] != 'B' && buffer[1] != 'B')
      ops[i] = 1;
    if (buffer[0] != 'C' && buffer[1] != 'C')
      ops[i] = 2;
  }
  if (solve(N, A, B, C)) {
    puts("Yes");
    for (int i = 0; i < N; ++i)
      printf("%c\\n", "ABC"[inc[i]]);
  } else {
    puts("No");
  }
}