Problem p00770 (C++) — buggy submission, verdict: Time Limit Exceeded

#include "bits/stdc++.h"
using namespace std;
bool is_prime[1000001];
int num[1010][1010];
int x[1000001];
int y[1000001];
int dp[1010][1010];
int dx[] = {1, 0, -1, 0};
int dy[] = {0, -1, 0, 1};
int main() {
  for (int i = 2; i <= 1000000; i++)
    is_prime[i] = 1;
  for (int i = 2; i <= 1000000; i++) {
    if (!is_prime[i])
      continue;
    for (int j = 2 * i; j <= 1000000; j += i)
      is_prime[j] = 0;
  }
  int len = 1;
  int cnt = 0;
  int dir = 0;
  memset(num, -1, sizeof(num));
  num[505][505] = 1;
  x[1] = 505;
  y[1] = 505;
  for (int i = 2; i <= 1000000; i++) {
    x[i] = x[i - 1] + dx[dir];
    y[i] = y[i - 1] + dy[dir];
    num[y[i]][x[i]] = i;
    cnt++;
    if (cnt == len) {
      cnt = 0;
      if (dir % 2)
        len++;
      (dir += 1) %= 4;
    }
  }
  int m, n;
  while (cin >> m >> n, m) {
    int sx = x[n];
    int sy = y[n];
    memset(dp, -1, sizeof(dp));
    dp[sy][sx] = 0;
    if (is_prime[num[sy][sx]])
      dp[sy][sx]++;
    for (int i = sy; i + 1 < 1010; i++) {
      for (int j = 0; j < 1010; j++) {
        if (num[i][j] == -1 || num[i][j] > m || dp[i][j] == -1)
          continue;
        for (int k = -1; k <= 1; k++) {
          int nx = j + k;
          if (0 > nx || nx >= 1010 || num[i + 1][nx] == -1 ||
              num[i + 1][nx] > m)
            continue;
          dp[i + 1][nx] =
              max(dp[i + 1][nx], dp[i][j] + is_prime[num[i + 1][nx]]);
        }
      }
    }
    int ans = -1;
    int t = -1;
    for (int i = 1; i <= m; i++) {
      if (!is_prime[i])
        continue;
      if (ans <= dp[y[i]][x[i]]) {
        ans = dp[y[i]][x[i]];
        t = i;
      }
    }
    if (ans == -1)
      cout << "0 0" << endl;
    else
      cout << ans << " " << t << endl;
  }
}


Error: TLE

Fixed submission:

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
map<P, int> num;
P pos[1000001];
map<P, int> sum;
set<P> vis;
int dx[] = {1, 0, -1, 0};
int dy[] = {0, -1, 0, 1};
bool is_prime[1000001];
int main() {
  memset(is_prime, -1, sizeof(is_prime));
  is_prime[1] = 0;
  for (int i = 2; i <= 1000000; i++) {
    if (!is_prime[i])
      continue;
    for (int j = i * 2; j <= 1000000; j += i)
      is_prime[j] = 0;
  }
  int x = 0, y = 0;
  int dir = 0;
  int len = 1;
  int cnt = 0;
  num[P(0, 0)] = 1;
  pos[1] = P(0, 0);
  for (int i = 2; i <= 1000000; i++) {
    x += dx[dir];
    y += dy[dir];
    num[P(x, y)] = i;
    pos[i] = P(x, y);
    cnt++;
    if (cnt == len) {
      cnt = 0;
      if (dir % 2)
        len++;
      (dir += 1) %= 4;
    }
  }
  int m, n;
  while (cin >> m >> n, m) {
    sum.clear();
    vis.clear();
    int sx, sy;
    sx = pos[n].first;
    sy = pos[n].second;
    int ans = -1;
    int t = -1;
    queue<P> Q;
    Q.push(P(sx, sy));
    vis.insert(P(sx, sy));
    while (!Q.empty()) {
      P now = Q.front();
      Q.pop();
      if (is_prime[num[now]]) {
        sum[now]++;
        if (ans < sum[now]) {
          ans = sum[now];
          t = num[now];
        } else if (ans == sum[now]) {
          t = max(t, num[now]);
        }
      }
      for (int i = -1; i <= 1; i++) {
        int x = now.first + i;
        int y = now.second + 1;
        if (num.find(P(x, y)) == num.end())
          continue;
        sum[P(x, y)] = max(sum[P(x, y)], sum[now]);
        if (vis.find(P(x, y)) != vis.end())
          continue;
        vis.insert(P(x, y));
        Q.push(P(x, y));
      }
    }
    if (ans == -1)
      cout << "0 0" << endl;
    else
      cout << ans << " " << t << endl;
  }
}