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

#include <bits/stdc++.h>
#define H 1000
#define W 1000
using namespace std;
int grid[H][W];
typedef pair<int, int> pii;

pii dp[(int)1e6 + 1]; // first cnt, second max
bool isprime[(int)1e6 + 1];
int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1};

void sieve(int n) {
  isprime[0] = isprime[1] = true;
  for (int i = 2; i <= n; i++) {
    if (isprime[i])
      continue;
    for (int j = 2 * i; j <= n; j += i)
      isprime[j] = true;
  }
}

bool renge(int x, int y) {
  if (0 <= x && x < W && 0 <= y && y < H)
    return true;
  return false;
}
vector<int> inM(int y, int x, int m) {
  vector<int> res;
  if (y + 1 >= H)
    return res;
  for (int i = -1; i < 2; i++) {
    if (x + i < 0 || W <= x + i)
      continue;
    if (grid[y + 1][x + i] <= m)
      res.push_back(i);
  }
  return res;
}

int main(int argc, char *argv[]) {
  sieve((int)1e6);
  int n = H * W, m, x = 0, y = 0, dir = 0;
  while (n > 0) {
    for (; renge(x + dx[dir], y + dy[dir]) &&
           grid[y + dy[dir]][x + dx[dir]] == 0;) {
      grid[y][x] = n;
      n--;
      x += dx[dir], y += dy[dir];
    }
    grid[y][x] = n;
    n--;
    dir++;
    dir %= 4;
    x += dx[dir], y += dy[dir];
  }
  while (cin >> m >> n, n) {
    memset(dp, 0, sizeof(dp));
    for (int i = H - 1; i >= 0; i--) {
      for (int j = 0; j < W; j++) {
        if (grid[i][j] <= m) {
          vector<int> cand = inM(i, j, m);
          for (int k = 0; k < cand.size(); k++) {
            dp[grid[i][j]] = max(dp[grid[i][j]], dp[grid[i + 1][j + cand[k]]]);
          }
          if (!isprime[grid[i][j]]) {
            if (dp[grid[i][j]].first == 0)
              dp[grid[i][j]].second = grid[i][j];
            dp[grid[i][j]].first++;
          }
        }
      }
    }
    cout << dp[n].first << " " << dp[n].second << endl;
  }

  return 0;
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>
#define H 1000
#define W 1000
using namespace std;
int grid[H][W];
typedef pair<int, int> pii;

pii dp[(int)1e6 + 1]; // first cnt, second max
bool isprime[(int)1e6 + 1];
int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1};

void sieve(int n) {
  isprime[0] = isprime[1] = true;
  for (int i = 2; i <= n; i++) {
    if (isprime[i])
      continue;
    for (int j = 2 * i; j <= n; j += i)
      isprime[j] = true;
  }
}

bool renge(int x, int y) {
  if (0 <= x && x < W && 0 <= y && y < H)
    return true;
  return false;
}
vector<int> inM(int y, int x, int m) {
  vector<int> res;
  for (int i = -1; i < 2; i++) {
    if (i + 1 >= H)
      continue;
    if (grid[y + 1][x + i] <= m)
      res.push_back(i);
  }
  return res;
}

int main(int argc, char *argv[]) {
  sieve((int)1e6);
  int n = H * W, m, x = 0, y = 0, dir = 0;
  while (n > 1) {
    for (; renge(x + dx[dir], y + dy[dir]) &&
           grid[y + dy[dir]][x + dx[dir]] == 0;) {
      grid[y][x] = n;
      n--;
      x += dx[dir], y += dy[dir];
    }
    grid[y][x] = n;
    n--;
    dir++;
    dir %= 4;
    x += dx[dir], y += dy[dir];
  }
  while (cin >> m >> n, n) {
    memset(dp, 0, sizeof(dp));
    for (int i = H - 1; i >= 0; i--) {
      for (int j = 0; j < W; j++) {
        if (grid[i][j] <= m) {
          vector<int> cand = inM(i, j, m);
          for (int k = 0; k < cand.size(); k++) {
            dp[grid[i][j]] = max(dp[grid[i][j]], dp[grid[i + 1][j + cand[k]]]);
          }
          if (!isprime[grid[i][j]]) {
            dp[grid[i][j]].first++;
            if (dp[grid[i][j]].second == 0)
              dp[grid[i][j]].second = max(grid[i][j], dp[grid[i][j]].second);
          }
        }
      }
    }
    cout << dp[n].first << " " << dp[n].second << endl;
  }

  return 0;
}