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

#include <algorithm>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
#define REP(i, j) for (int i = 0; i < (int)(j); ++i)
#define FOR(i, j, k) for (int i = (int)(j); i < (int)(k); ++i)
#define SORT(v) sort((v).begin(), (v).end())
#define REVERSE(v) reverse((v).begin(), (v).end())
typedef pair<int, int> P;
const int MAX_M = 1000001;
const int MAX_C = 1000;
const int INF = 1e9;
#define y first
#define x second

map<P, int> ptoi;
bool isp[MAX_M];
P dp[MAX_C][MAX_C];

void make_prime() {
  REP(i, MAX_M) isp[i] = true;
  isp[0] = isp[1] = false;
  FOR(i, 2, sqrt(MAX_M) + 1) {
    if (!isp[i])
      continue;
    for (int j = i + i; j < MAX_M; j += i)
      isp[j] = false;
  }
}

void init() {
  P now = P(MAX_C / 2, MAX_C / 2);
  int pls = 1, l = 1, step = 0, d = 0;
  FOR(i, 1, MAX_M) {
    ptoi[now] = i;
    if (d == 0)
      now.x += 1;
    else if (d == 1)
      now.y -= 1;
    else if (d == 2)
      now.x -= 1;
    else if (d == 3)
      now.y += 1;
    ++step;
    if (step >= l) {
      d = (d + 1) % 4;
      step = 0;
    }
    if (i != 1 && (d == 0 || d == 2) && step == 0)
      ++l;
  }
}

int main() {
  make_prime();
  init();
  int M, N;
  while (cin >> M >> N && (N && M)) {
    REP(i, MAX_C) REP(j, MAX_C) dp[i][j] = P(-1, -1);
    REP(i, MAX_C)
    REP(j, MAX_C) if (ptoi[P(i, j)] == N) dp[i][j] =
        (isp[N] ? P(1, N) : P(0, -1));
    P ans = P(-1, -1);
    REP(y, MAX_C) {
      REP(x, MAX_C) {
        if (dp[y][x].first == -1 || ptoi.find(P(y, x)) == ptoi.end() ||
            ptoi[P(y, x)] > M)
          continue;
        ans = max(ans, dp[y][x]);
        for (int mx = -1; mx <= 1; ++mx) {
          int ny = y + 1, nx = x + mx;
          if (ny < 0 || nx < 0 || ny >= MAX_C || nx >= MAX_C ||
              ptoi.find(P(ny, nx)) == ptoi.end() || ptoi[P(ny, nx)] > M)
            continue;
          int cnt = dp[y][x].first + (isp[ptoi[P(ny, nx)]] ? 1 : 0),
              num = (isp[ptoi[P(ny, nx)]] ? ptoi[P(ny, nx)] : dp[y][x].second);
          if (cnt > dp[ny][nx].first ||
              (cnt == dp[ny][nx].first && num > dp[ny][nx].second))
            dp[ny][nx] = P(cnt, num);
        }
      }
    }
    if (ans.first == 0)
      cout << "0 0" << endl;
    else
      cout << ans.first << " " << ans.second << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
#define REP(i, j) for (int i = 0; i < (int)(j); ++i)
#define FOR(i, j, k) for (int i = (int)(j); i < (int)(k); ++i)
#define SORT(v) sort((v).begin(), (v).end())
#define REVERSE(v) reverse((v).begin(), (v).end())
typedef pair<int, int> P;
const int MAX_M = 1000001;
const int MAX_C = 1000;
const int INF = 1e9;
#define y first
#define x second

map<P, int> ptoi;
bool isp[MAX_M];
P dp[MAX_C][MAX_C];

void make_prime() {
  REP(i, MAX_M) isp[i] = true;
  isp[0] = isp[1] = false;
  FOR(i, 2, sqrt(MAX_M) + 1) {
    if (!isp[i])
      continue;
    for (int j = i + i; j < MAX_M; j += i)
      isp[j] = false;
  }
}

void init() {
  P now = P(MAX_C / 2, MAX_C / 2);
  int pls = 1, l = 1, step = 0, d = 0;
  FOR(i, 1, MAX_M) {
    ptoi[now] = i;
    if (d == 0)
      now.x += 1;
    else if (d == 1)
      now.y -= 1;
    else if (d == 2)
      now.x -= 1;
    else if (d == 3)
      now.y += 1;
    ++step;
    if (step >= l) {
      d = (d + 1) % 4;
      step = 0;
    }
    if (i != 1 && (d == 0 || d == 2) && step == 0)
      ++l;
  }
}

int main() {
  make_prime();
  init();
  int M, N;
  while (cin >> M >> N && (N && M)) {
    REP(i, MAX_C) REP(j, MAX_C) dp[i][j] = P(-1, -1);
    REP(i, MAX_C)
    REP(j, MAX_C) if (ptoi[P(i, j)] == N) dp[i][j] =
        (isp[N] ? P(1, N) : P(0, -1));
    P ans = P(-1, -1);
    REP(y, MAX_C) {
      REP(x, MAX_C) {
        if (dp[y][x].first == -1 || ptoi.find(P(y, x)) == ptoi.end())
          continue;
        ans = max(ans, dp[y][x]);
        for (int mx = -1; mx <= 1; ++mx) {
          int ny = y + 1, nx = x + mx;
          if (ny < 0 || nx < 0 || ny >= MAX_C || nx >= MAX_C ||
              ptoi.find(P(ny, nx)) == ptoi.end())
            continue;
          int cnt = dp[y][x].first + (isp[ptoi[P(ny, nx)]] ? 1 : 0),
              num = (isp[ptoi[P(ny, nx)]] ? ptoi[P(ny, nx)] : dp[y][x].second);
          if (num > M)
            continue;
          if (cnt > dp[ny][nx].first ||
              (cnt == dp[ny][nx].first && num > dp[ny][nx].second))
            dp[ny][nx] = P(cnt, num);
        }
      }
    }
    if (ans.first == 0)
      cout << "0 0" << endl;
    else
      cout << ans.first << " " << ans.second << endl;
  }
  return 0;
}