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

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); i++)
using namespace std;

#define MAX 1000000
int m, n;
int caves[1000][1000];

int isPrime[MAX + 1];
void sieve() {
  isPrime[0] = isPrime[1] = false;
  for (int i = 2; i <= MAX; i++)
    isPrime[i] = true;
  for (int i = 2; i <= MAX; i++)
    if (isPrime[i])
      for (int j = i * 2; j <= MAX; j += i)
        isPrime[j] = false;
}

int Pow[1000];
void mkcaves() {
  Pow[0] = 1;
  for (int i = 1; i < 1000; i++)
    Pow[i] = Pow[i - 1] + 2 * i + 1;
  int x = 499, y = 500;
  for (int i = 1; i <= 1000; i++) {
    if (i % 2) {
      for (int j = Pow[i - 1] - 2 * i + 2; j <= Pow[i - 1] - i; j++)
        caves[x][y++] = isPrime[j] ? j : j * -1;
      for (int j = Pow[i - 1] - i + 1; j <= Pow[i - 1]; j++)
        caves[x++][y] = isPrime[j] ? j : j * -1;
    } else {
      for (int j = Pow[i - 1] + -2 * i + 2; j <= Pow[i - 1] - i; j++)
        caves[x][y--] = isPrime[j] ? j : j * -1;
      for (int j = Pow[i - 1] - i + 1; j <= Pow[i - 1]; j++)
        caves[x--][y] = isPrime[j] ? j : j * -1;
    }
  }
}

void print(int ary[1000][1000]) {
  for (int i = 500 - sqrt(m) / 2 + 1; i < 500 + sqrt(m) / 2; i++) {
    for (int j = 500 - sqrt(m) / 2; j < 500 + sqrt(m) / 2 - 1; j++)
      printf("%3d ", ary[j][i]);
    putchar('\\n');
  }
}

int max3(int a, int b, int c) {
  int max = a;
  if (b > max)
    max = b;
  if (c > max)
    max = c;
  return max;
}

int dp[1000][1000];
int cp[1000][1000];
void solve() {
  // copy caves
  rep(i, 1000) rep(j, 1000) cp[j][i] = (0 < caves[j][i] && caves[j][i] <= m);

  // print(cp);

  // reset dp
  rep(i, 1000) rep(j, 1000) dp[j][i] = 0;

  if (!isPrime[n])
    n *= -1;

  int sx, sy;
  bool f = false;
  rep(i, 1000) {
    rep(j, 1000) {
      if (caves[j][i] == n) {
        sx = j;
        sy = i;
        f = true;
        break;
      }
    }
    if (f)
      break;
  }
  // printf("start = (%d,%d)\\n",sx,sy);

  dp[sx][sy] = cp[sx][sy];
  int nmax = 0;
  for (int i = 1; i <= sqrt(m) + 1 && sy + i < 1000; i++) {
    int jmin = -i, jmax = i;
    if (sx + jmin <= 0) {
      dp[0][sy + i] = cp[0][sy + i] + max(dp[0][sy + i - 1], dp[1][sy + i - 1]);
      if (dp[0][sy + i] > nmax)
        nmax = dp[0][sy + i];
      jmin = 1 - sx;
    }
    if (sx + jmax >= 999) {
      dp[999][sy + i] =
          cp[999][sy + i] + max(dp[998][sy + i - 1], dp[999][sy + i - 1]);
      if (dp[999][sy + i] > nmax)
        nmax = dp[999][sy + i];
      jmax = 998 - sx;
    }
    for (int j = jmin; j <= jmax; j++) {
      dp[sx + j][sy + i] =
          cp[sx + j][sy + i] + max3(dp[sx + j - 1][sy + i - 1],
                                    dp[sx + j][sy + i - 1],
                                    dp[sx + j + 1][sy + i - 1]);
      if (dp[sx + j][sy + i] > nmax)
        nmax = dp[sx + j][sy + i];
    }
  }
  // puts("~nmax");

  int pmax = 0;
  for (int i = 0; i < sqrt(m) + 1 && sy + i < 1000; i++) {
    int jmin = -i, jmax = i;
    if (sx + jmin <= 0) {
      //      dp[0][sy+i] = cp[0][sy+i]
      //	+ max(dp[0][sy+i-1], dp[1][sy+i-1]);
      jmin = 1 - sx;
    }
    if (sx + jmax >= 999) {
      // dp[999][sy+i] = cp[999][sy+i]
      //	+ max(dp[998][sy+i-1], dp[999][sy+i-1]);
      jmax = 998 - sx;
    }
    for (int j = jmin; j <= jmax; j++) {
      if (cp[sx + j][sy + i] && dp[sx + j][sy + i] == nmax &&
          pmax < caves[sx + j][sy + i])
        pmax = caves[sx + j][sy + i];
    }
  }
  // puts("~pmax");

  // print(dp);

  printf("%d %d\\n", nmax, pmax);
}

int main() {
  sieve();
  mkcaves();
  for (;;) {
    scanf("%d %d", &m, &n);
    if (!(m + n))
      break;
    solve();
  }
  return 0;
}

Error: WA

Fixed submission:

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); i++)
using namespace std;

#define MAX 1000000
int m, n;
int caves[1000][1000];

int isPrime[MAX + 1];
void sieve() {
  isPrime[0] = isPrime[1] = false;
  for (int i = 2; i <= MAX; i++)
    isPrime[i] = true;
  for (int i = 2; i <= MAX; i++)
    if (isPrime[i])
      for (int j = i * 2; j <= MAX; j += i)
        isPrime[j] = false;
}

int Pow[1000];
void mkcaves() {
  Pow[0] = 1;
  for (int i = 1; i < 1000; i++)
    Pow[i] = Pow[i - 1] + 2 * i + 1;
  int x = 499, y = 500;
  for (int i = 1; i <= 1000; i++) {
    if (i % 2) {
      for (int j = Pow[i - 1] - 2 * i + 2; j <= Pow[i - 1] - i; j++)
        caves[x][y++] = isPrime[j] ? j : j * -1;
      for (int j = Pow[i - 1] - i + 1; j <= Pow[i - 1]; j++)
        caves[x++][y] = isPrime[j] ? j : j * -1;
    } else {
      for (int j = Pow[i - 1] + -2 * i + 2; j <= Pow[i - 1] - i; j++)
        caves[x][y--] = isPrime[j] ? j : j * -1;
      for (int j = Pow[i - 1] - i + 1; j <= Pow[i - 1]; j++)
        caves[x--][y] = isPrime[j] ? j : j * -1;
    }
  }
}

void print(int ary[1000][1000]) {
  for (int i = 500 - sqrt(m) / 2 + 1; i < 500 + sqrt(m) / 2; i++) {
    for (int j = 500 - sqrt(m) / 2; j < 500 + sqrt(m) / 2 - 1; j++)
      printf("%3d ", ary[j][i]);
    putchar('\\n');
  }
}

int max3(int a, int b, int c) {
  int max = a;
  if (b > max)
    max = b;
  if (c > max)
    max = c;
  return max;
}

int dp[1000][1000];
int cp[1000][1000];
void solve() {
  // copy caves
  rep(i, 1000) rep(j, 1000) cp[j][i] = (0 < caves[j][i] && caves[j][i] <= m);

  // print(cp);

  // reset dp
  rep(i, 1000) rep(j, 1000) dp[j][i] = 0;

  if (!isPrime[n])
    n *= -1;

  int sx, sy;
  bool f = false;
  rep(i, 1000) {
    rep(j, 1000) {
      if (caves[j][i] == n) {
        sx = j;
        sy = i;
        f = true;
        break;
      }
    }
    if (f)
      break;
  }
  // printf("start = (%d,%d)\\n",sx,sy);

  dp[sx][sy] = cp[sx][sy];
  int nmax = 0;
  for (int i = 1; i <= sqrt(m) + 3 && sy + i < 1000; i++) {
    for (int j = -i; j <= i; j++) {
      dp[sx + j][sy + i] =
          cp[sx + j][sy + i] + max3(dp[sx + j - 1][sy + i - 1],
                                    dp[sx + j][sy + i - 1],
                                    dp[sx + j + 1][sy + i - 1]);
      if (dp[sx + j][sy + i] > nmax)
        nmax = dp[sx + j][sy + i];
    }
  }

  // puts("~nmax");

  int pmax = 0;
  for (int i = 0; i < sqrt(m) + 3 && sy + i < 1000; i++) {
    for (int j = -i; j <= i; j++) {
      if (cp[sx + j][sy + i] && dp[sx + j][sy + i] == nmax &&
          pmax < caves[sx + j][sy + i])
        pmax = caves[sx + j][sy + i];
    }
  }
  // puts("~pmax");

  // print(dp);

  printf("%d %d\\n", nmax, pmax);
}

int main() {
  sieve();
  mkcaves();
  for (;;) {
    scanf("%d %d", &m, &n);
    if (!(m + n))
      break;
    solve();
  }
  return 0;
}