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

#include <cassert>
#include <climits>
#include <cmath>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>

#define M 61
#define H 11
#define W 11

using namespace std;

const int infty = INT_MAX;
const int di[] = {-1, 0, 1, 0};
const int dj[] = {0, 1, 0, -1};

struct state {
  int o, i, j, cost;
  int l, r;
  state() : o(0), i(-1), j(-1), cost(infty), l(-1), r(-1) {}
  state(int o, int i, int j, int l, int r, int cost)
      : o(o), i(i), j(j), cost(cost), l(l), r(r) {}
  bool operator>(const state &t) const { return cost > t.cost; }
};

bool isinside(int i, int j, int h, int w) {
  return 0 <= i && i < h && 0 <= j && j < w;
}

int dijkstra(int o, int maxO, int maxC, int h, int w, int g[H][W]) {
  int ret = infty;
  priority_queue<state, vector<state>, greater<state>> pq;
  static int A[M][H][W][W][W];
  static bool vis[M][H][W][W][W];

  o = min(maxO, o);

  for (int i = 0; i < M; ++i) {
    for (int j = 0; j < H; ++j) {
      for (int k = 0; k < W; ++k) {
        for (int l = 0; l < W; ++l) {
          for (int m = 0; m < W; ++m) {
            A[i][j][k][l][m] = infty;
            vis[i][j][k][l][m] = false;
          }
        }
      }
    }
  }

  for (int stj = 0; stj < w; ++stj) {
    int ic;
    int io;
    if (o <= 1)
      return infty;
    if (g[0][stj] > 0) {
      ic = 0;
      io = min(maxO, o + g[0][stj] - 1);
    } else {
      ic = -g[0][stj];
      io = o - 1;
    }
    state init(io, 0, stj, stj, stj, ic);
    A[io][0][stj][stj][stj] = ic;
    pq.push(init);
  }

  while (!pq.empty()) {
    state nst = pq.top();
    pq.pop();

    if (vis[nst.o][nst.i][nst.j][nst.l][nst.r])
      continue;
    else
      vis[nst.o][nst.i][nst.j][nst.l][nst.r] = true;

    if (nst.i == h - 1 && nst.o >= 1)
      ret = min(ret, nst.cost);

    // printf("(%d,%d) with oxygen %d cost = %d\\n", nst.i, nst.j, nst.o,
    // nst.cost);

    for (int k = 1; k < 4; ++k) {
      state next = nst;
      next.i += di[k];
      next.j += dj[k];
      if (isinside(next.i, next.j, h, w)) {
        if (next.o - 1 <= 0)
          continue;
        if (k == 2) {
          next.l = W + 1;
          next.r = -1;
        }
        if (g[next.i][next.j] > 0) {
          int d_o = g[next.i][next.j];
          if (next.l <= next.j && next.j <= next.r)
            d_o = 0;
          next.o += d_o;
        } else {
          int d_c = -g[next.i][next.j];
          if (next.l <= next.j && next.j <= next.r)
            d_c = 0;
          next.cost += d_c;
        }
        next.o = min(maxO, next.o - 1);
        next.l = min(next.l, next.j);
        next.r = max(next.r, next.j);
        if (next.cost > maxC)
          continue;

        if (next.o > 0) {
          if (next.cost < A[next.o][next.i][next.j][next.l][next.r]) {
            A[next.o][next.i][next.j][next.l][next.r] = next.cost;
            if (!vis[next.o][next.i][next.j][next.l][next.r])
              pq.push(next);
          }
        }
      }
    }
  }
  return ret;
}

int main() {
  while (true) {
    int w, h;
    int g[H][W];
    int f, m, o;
    int res = infty;
    scanf("%d%d", &w, &h);
    if (w == 0 && h == 0)
      break;
    scanf("%d%d%d", &f, &m, &o);

    for (int i = 0; i < h; ++i) {
      for (int j = 0; j < w; ++j) {
        scanf("%d", &g[i][j]);
      }
    }

    res = dijkstra(o, m, f, h, w, g);
    if (res > f) {
      puts("NA");
    } else {
      printf("%d\\n", res);
    }
  }
  return 0;
}

Error: 0

Fixed submission:

#include <cassert>
#include <climits>
#include <cmath>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>

#define M 51
#define H 11
#define W 11

using namespace std;

const int infty = INT_MAX;
const int di[] = {-1, 0, 1, 0};
const int dj[] = {0, 1, 0, -1};

struct state {
  int o, i, j, cost;
  int l, r;
  state() : o(0), i(-1), j(-1), cost(infty), l(-1), r(-1) {}
  state(int o, int i, int j, int l, int r, int cost)
      : o(o), i(i), j(j), cost(cost), l(l), r(r) {}
  bool operator>(const state &t) const { return cost > t.cost; }
};

bool isinside(int i, int j, int h, int w) {
  return 0 <= i && i < h && 0 <= j && j < w;
}

int dijkstra(int o, int maxO, int maxC, int h, int w, int g[H][W]) {
  int ret = infty;
  priority_queue<state, vector<state>, greater<state>> pq;
  static int A[M][H][W][W][W];
  static bool vis[M][H][W][W][W];

  if (o <= 1)
    return ret;
  o = min(maxO, o);

  for (int i = 0; i < M; ++i) {
    for (int j = 0; j < H; ++j) {
      for (int k = 0; k < W; ++k) {
        for (int l = 0; l < W; ++l) {
          for (int m = 0; m < W; ++m) {
            A[i][j][k][l][m] = infty;
            vis[i][j][k][l][m] = false;
          }
        }
      }
    }
  }

  for (int stj = 0; stj < w; ++stj) {
    int ic;
    int io;
    if (o <= 1)
      return infty;
    if (g[0][stj] > 0) {
      ic = 0;
      io = o + g[0][stj] - 1;
    } else {
      ic = -g[0][stj];
      io = o - 1;
    }
    state init(io, 0, stj, stj, stj, ic);
    A[io][0][stj][stj][stj] = ic;
    pq.push(init);
  }

  while (!pq.empty()) {
    state nst = pq.top();
    pq.pop();

    if (vis[nst.o][nst.i][nst.j][nst.l][nst.r])
      continue;
    else
      vis[nst.o][nst.i][nst.j][nst.l][nst.r] = true;

    if (nst.i == h - 1 && nst.o >= 1)
      ret = min(ret, nst.cost);

    // printf("(%d,%d) with oxygen %d cost = %d\\n", nst.i, nst.j, nst.o,
    // nst.cost);

    for (int k = 1; k < 4; ++k) {
      state next = nst;
      next.i += di[k];
      next.j += dj[k];
      if (isinside(next.i, next.j, h, w)) {
        if (next.o - 1 <= 0)
          continue;
        if (k == 2) {
          next.l = W + 1;
          next.r = -1;
        }
        if (g[next.i][next.j] > 0) {
          int d_o = g[next.i][next.j];
          if (next.l <= next.j && next.j <= next.r)
            d_o = 0;
          next.o += d_o;
        } else {
          int d_c = -g[next.i][next.j];
          if (next.l <= next.j && next.j <= next.r)
            d_c = 0;
          next.cost += d_c;
        }
        next.o = min(maxO, next.o - 1);
        next.l = min(next.l, next.j);
        next.r = max(next.r, next.j);
        if (next.cost > maxC)
          continue;

        if (next.o > 0) {
          if (next.cost < A[next.o][next.i][next.j][next.l][next.r]) {
            A[next.o][next.i][next.j][next.l][next.r] = next.cost;
            pq.push(next);
          }
        }
      }
    }
  }
  return ret;
}

int main() {
  while (true) {
    int w, h;
    int g[H][W];
    int f, m, o;
    int res = infty;
    scanf("%d%d", &w, &h);
    if (w == 0 && h == 0)
      break;
    scanf("%d%d%d", &f, &m, &o);

    for (int i = 0; i < h; ++i) {
      for (int j = 0; j < w; ++j) {
        scanf("%d", &g[i][j]);
      }
    }

    res = dijkstra(o, m, f, h, w, g);
    if (res > f) {
      puts("NA");
    } else {
      printf("%d\\n", res);
    }
  }
  return 0;
}