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

#include <algorithm>
#include <cassert>
#include <iostream>
#include <vector>
#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define inf (1 << 29)
#define MAX 2000
using namespace std;
struct P {
  int x, y, index;
  P(int x = inf, int y = inf, int index = inf) : x(x), y(y), index(index) {}
};
int h, w, sx, sy, gx, gy, sindex, gindex;
int mincost[6000]; // mincost[j] := 現在地j の最小コスト
char G[MAX][MAX];
vector<P> vec[7];

int main() {
  while (cin >> w >> h, w | h) {
    rep(i, 7) vec[i].clear();

    int index = 0;
    rep(i, h) rep(j, w) {
      cin >> G[i][j];
      if (G[i][j] == 'S')
        vec[5].push_back(P(j, i, index++));
      else if (G[i][j] == 'G')
        vec[6].push_back(P(j, i, index++));
      else if (G[i][j] == '1')
        vec[0].push_back(P(j, i, index++));
      else if (G[i][j] == '2')
        vec[1].push_back(P(j, i, index++));
      else if (G[i][j] == '3')
        vec[2].push_back(P(j, i, index++));
      else if (G[i][j] == '4')
        vec[3].push_back(P(j, i, index++));
      else if (G[i][j] == '5')
        vec[4].push_back(P(j, i, index++));
    }
    assert(index < 6000);
    // assert((vec[5].size() == 1 || vec[5].size() == 0) && (vec[6].size() == 1
    // || vec[6].size() == 0));
    int ans_cost, ans_first;
    ans_cost = inf;
    rep(i, 5) // 最初に選んだぽきもん
    {
      rep(j, 6000) mincost[j] = inf;
      rep(j, vec[5].size()) mincost[vec[5][j].index] = 0;

      int npk = (i + 1) % 5;
      for (int k = 0; k < vec[5].size(); k++) {
        for (int j = 0; j < vec[npk].size(); j++) {
          int nx = vec[npk][j].x;
          int ny = vec[npk][j].y;
          mincost[vec[npk][j].index] =
              abs(nx - vec[5][k].x) + abs(ny - vec[5][k].y);
        }
      }

      for (int cur = npk, cnt = 0; cnt < 3; cnt++, cur = (cur + 1) % 5) {
        for (int j = 0; j < vec[cur].size(); j++) {
          int next = (cur + 1) % 5;

          int x = vec[cur][j].x;
          int y = vec[cur][j].y;
          for (int k = 0; k < vec[next].size(); k++) {
            int nx = vec[next][k].x;
            int ny = vec[next][k].y;
            mincost[vec[next][k].index] =
                min(mincost[vec[next][k].index],
                    mincost[vec[cur][j].index] + abs(nx - x) + abs(ny - y));
          }
        }
        if (cnt == 3)
          assert(cur == (i + 3) % 5);
      }

      int last = (i + 4) % 5;
      for (int k = 0; k < vec[6].size(); k++) {
        for (int j = 0; j < vec[last].size(); j++) {
          int nx = vec[last][j].x;
          int ny = vec[last][j].y;

          if (ans_cost > mincost[vec[last][j].index] + abs(nx - vec[6][k].x) +
                             abs(ny - vec[6][k].y)) {
            ans_cost = mincost[vec[last][j].index] + abs(nx - vec[6][k].x) +
                       abs(ny - vec[6][k].y);
            ans_first = i + 1;
          }
        }
      }
    }
    if (ans_cost == inf)
      cout << "NA" << endl;
    else
      cout << ans_first << " " << ans_cost << endl;
  }
  return 0;
}

Error: -6
22f3659d-d85e-499a-b22d-1e27917b9b16.out: /home/alex/Documents/bug-detection/input/Project_CodeNet/data/p00215/C++/s902688161.cpp:39: int main(): Assertion `(vec[5].size() == 1 || vec[5].size() == 0) && (vec[6].size() == 1 || vec[6].size() == 0)' failed.


Fixed submission:

#include <algorithm>
#include <cassert>
#include <iostream>
#include <vector>
#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define inf (1 << 29)
#define MAX 2000
using namespace std;
struct P {
  int x, y, index;
  P(int x = inf, int y = inf, int index = inf) : x(x), y(y), index(index) {}
};
int h, w, sx, sy, gx, gy, sindex, gindex;
int mincost[6000]; // mincost[j] := 現在地j の最小コスト
char G[MAX][MAX];
vector<P> vec[7];

int main() {
  while (cin >> w >> h, w | h) {
    rep(i, 5) vec[i].clear();

    int index = 0;
    rep(i, h) rep(j, w) {
      cin >> G[i][j];
      if (G[i][j] == 'S')
        vec[5].push_back(P(j, i, index++));
      else if (G[i][j] == 'G')
        vec[6].push_back(P(j, i, index++));
      else if (G[i][j] == '1')
        vec[0].push_back(P(j, i, index++));
      else if (G[i][j] == '2')
        vec[1].push_back(P(j, i, index++));
      else if (G[i][j] == '3')
        vec[2].push_back(P(j, i, index++));
      else if (G[i][j] == '4')
        vec[3].push_back(P(j, i, index++));
      else if (G[i][j] == '5')
        vec[4].push_back(P(j, i, index++));
    }
    assert(index < 6000);
    assert((vec[5].size() == 1 || vec[5].size() == 0) &&
           (vec[6].size() == 1 || vec[6].size() == 0));
    int ans_cost, ans_first;
    ans_cost = inf;
    rep(i, 5) // 最初に選んだぽきもん
    {
      rep(j, 6000) mincost[j] = inf;
      mincost[vec[5][0].index] = 0;
      int npk = (i + 1) % 5;
      for (int j = 0; j < vec[npk].size(); j++) {
        int nx = vec[npk][j].x;
        int ny = vec[npk][j].y;
        mincost[vec[npk][j].index] =
            abs(nx - vec[5][0].x) + abs(ny - vec[5][0].y);
      }

      for (int cur = npk, cnt = 0; cnt < 3; cnt++, cur = (cur + 1) % 5) {
        for (int j = 0; j < vec[cur].size(); j++) {
          int next = (cur + 1) % 5;

          int x = vec[cur][j].x;
          int y = vec[cur][j].y;
          for (int k = 0; k < vec[next].size(); k++) {
            int nx = vec[next][k].x;
            int ny = vec[next][k].y;
            mincost[vec[next][k].index] =
                min(mincost[vec[next][k].index],
                    mincost[vec[cur][j].index] + abs(nx - x) + abs(ny - y));
          }
        }
        if (cnt == 3)
          assert(cur == (i + 3) % 5);
      }

      int last = (i + 4) % 5;
      for (int j = 0; j < vec[last].size(); j++) {
        int nx = vec[last][j].x;
        int ny = vec[last][j].y;

        if (ans_cost > mincost[vec[last][j].index] + abs(nx - vec[6][0].x) +
                           abs(ny - vec[6][0].y)) {
          ans_cost = mincost[vec[last][j].index] + abs(nx - vec[6][0].x) +
                     abs(ny - vec[6][0].y);
          ans_first = i + 1;
        }
      }
    }
    if (ans_cost == inf)
      cout << "NA" << endl;
    else
      cout << ans_first << " " << ans_cost << endl;
  }
  return 0;
}