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

#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>

#define MOD7 1000000007
#define MOD9 1000000009

#define rep(i, n) for (int i = 0; i < (n); i++)
#define REP(i, a, n) for (int i = (a); i <= (n); i++)
#define all(a) (a).begin(), (a).end()

using namespace std;

int dx[4] = {0, -1, 0, 1};
int dy[4] = {-1, 0, 1, 0};

int nextInt() {
  int a;
  cin >> a;
  return a;
}
char nextChar() {
  char a;
  cin >> a;
  return a;
}
double nextDouble() {
  double a;
  cin >> a;
  return a;
}
string nextString() {
  string a;
  cin >> a;
  return a;
}

void inputVector(vector<int> &v, int &n) {
  rep(i, n) { v.push_back(nextInt()); }
}
void inputVector(vector<double> &v, int &n) {
  rep(i, n) { v.push_back(nextDouble()); }
}
void inputVector(vector<string> &v, int &n) {
  rep(i, n) { v.push_back(nextString()); }
}

const int GETA = 502;

bool isprime[1000010];
pair<int, int> dp[1004][1004];

map<int, pair<short, short>> map1;
map<pair<short, short>, int> map2;

pair<int, int> solve(int n, int m) {
  if (n > m)
    return make_pair(0, 0);

  pair<short, short> &pos = map1[n];
  if (dp[pos.first][pos.second].first != -1)
    return dp[pos.first][pos.second];

  pair<int, int> ret = make_pair(0, 0);
  REP(i, -1, 1) {
    pair<short, short> nt = make_pair(pos.first + i, pos.second + 1);
    if (map2.find(nt) == map2.end())
      continue;
    pair<int, int> res = solve(map2[nt], m);
    if (res.first > ret.first ||
        (res.first == ret.first && res.second > ret.second)) {
      ret = res;
    }
  }
  if (isprime[n]) {
    ret.first++;
    if (ret.first == 1) {
      ret.second = n;
    }
  }
  dp[pos.first][pos.second] = ret;
  return ret;
}

signed main() {
  rep(i, 1000001) isprime[i] = true;
  isprime[1] = false;
  REP(i, 2, 1000000) {
    if (!isprime[i])
      continue;
    for (int j = 2 * i; j <= 1000000; j += i) {
      isprime[j] = false;
    }
  }

  int x = GETA, y = GETA;
  int dir;
  int size = 1;
  int left;
  for (int pt = 1; pt <= 1000000; pt++) {
    pair<short, short> pr = make_pair(x, y);
    map1[pt] = pr;
    map2[pr] = pt;
    if (pt == size * size) {
      x++;
      size += 2;
      dir = 0;
      left = size - 2;
    } else {
      x += dx[dir];
      y += dy[dir];
      left--;
      if (left == 0) {
        dir++;
        left = size - 1;
      }
    }
  }

  int m, n;
  while (cin >> m >> n) {
    if (m == 0)
      break;

    REP(i, 1, m) {
      pair<short, short> &pr = map1[i];
      dp[pr.first][pr.second] = make_pair(-1, 0);
    }

    pair<int, int> ret = solve(n, m);

    cout << ret.first << ' ' << ret.second << endl;
  }

  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>

#define MOD7 1000000007
#define MOD9 1000000009

#define rep(i, n) for (int i = 0; i < (n); i++)
#define REP(i, a, n) for (int i = (a); i <= (n); i++)
#define all(a) (a).begin(), (a).end()

using namespace std;

int dx[4] = {0, -1, 0, 1};
int dy[4] = {-1, 0, 1, 0};

int nextInt() {
  int a;
  cin >> a;
  return a;
}
char nextChar() {
  char a;
  cin >> a;
  return a;
}
double nextDouble() {
  double a;
  cin >> a;
  return a;
}
string nextString() {
  string a;
  cin >> a;
  return a;
}

void inputVector(vector<int> &v, int &n) {
  rep(i, n) { v.push_back(nextInt()); }
}
void inputVector(vector<double> &v, int &n) {
  rep(i, n) { v.push_back(nextDouble()); }
}
void inputVector(vector<string> &v, int &n) {
  rep(i, n) { v.push_back(nextString()); }
}

const int GETA = 502;

bool isprime[1000010];
pair<int, int> dp[1004][1004];

map<int, pair<int, int>> map1;
map<pair<int, int>, int> map2;

pair<int, int> solve(int n, int m) {
  if (n > m)
    return make_pair(0, 0);

  pair<int, int> &pos = map1[n];
  if (dp[pos.first][pos.second].first != -1)
    return dp[pos.first][pos.second];

  pair<int, int> ret = make_pair(0, 0);
  REP(i, -1, 1) {
    pair<int, int> nt = make_pair(pos.first + i, pos.second + 1);
    if (map2.find(nt) == map2.end())
      continue;
    pair<int, int> res = solve(map2[nt], m);
    if (res.first > ret.first ||
        (res.first == ret.first && res.second > ret.second)) {
      ret = res;
    }
  }
  if (isprime[n]) {
    ret.first++;
    if (ret.first == 1) {
      ret.second = n;
    }
  }
  dp[pos.first][pos.second] = ret;
  return ret;
}

signed main() {
  rep(i, 1000001) isprime[i] = true;
  isprime[1] = false;
  REP(i, 2, 1000000) {
    if (!isprime[i])
      continue;
    for (int j = 2 * i; j <= 1000000; j += i) {
      isprime[j] = false;
    }
  }

  int x = GETA, y = GETA;
  int dir;
  int size = 1;
  int left;
  for (int pt = 1; pt <= 1000000; pt++) {
    pair<int, int> pr = make_pair(x, y);
    map1[pt] = pr;
    map2[pr] = pt;
    if (pt == size * size) {
      x++;
      size += 2;
      dir = 0;
      left = size - 2;
    } else {
      x += dx[dir];
      y += dy[dir];
      left--;
      if (left == 0) {
        dir++;
        left = size - 1;
      }
    }
  }

  int m, n;
  while (cin >> m >> n) {
    if (m == 0)
      break;

    REP(i, 1, m) {
      pair<int, int> &pr = map1[i];
      dp[pr.first][pr.second] = make_pair(-1, 0);
    }

    pair<int, int> ret = solve(n, m);

    cout << ret.first << ' ' << ret.second << endl;
  }

  return 0;
}