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

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

using namespace std;

const int N = 4;
const int MAX_E = 72;
const char ope[] = {'+', '-', '*'};

bool is_end(vector<int> a) {
  REP(i, a.size()) if (a[i] != 0) return false;
  return true;
}

int calc(int type, int val, int x) {
  if (type == 0)
    return val - x;
  if (type == 1)
    return x - val;
  if (type == 2)
    return val / x;
}

bool used[5][5][300];
string memo[5][5][300];
string rec(const vector<int> &nums, int l, int r, int val) {
  if (used[l][r][val + MAX_E])
    return memo[l][r][val + MAX_E];
  used[l][r][val + MAX_E] = true;
  string &res = memo[l][r][val + MAX_E];

  if (r - l == 1) {
    if (nums[l] == val) {
      return res = to_string(val);
    } else {
      return res = "";
    }
  }

  for (int k = 1; l + k < r; k++) {
    for (int x = -MAX_E; x <= MAX_E; x++) {
      for (int type = 0; type < 3; type++) {
        if (type == 2 && (x == 0 || val % x != 0))
          continue;
        int y = calc(type, val, x);
        string ls = rec(nums, l, l + k, x);
        string rs = rec(nums, l + k, r, y);
        if (ls == "")
          continue;
        if (rs == "")
          continue;
        if (nums.size() == 4)
          return res = "(" + ls + ope[type] + rs + ")";
      }
    }
  }

  return res = "";
}

int main() {
  while (true) {
    vector<int> nums(N);
    REP(i, N) cin >> nums[i];
    if (is_end(nums))
      break;

    bool exist = false;
    sort(nums.begin(), nums.end());
    do {
      memset(used, 0, sizeof(used));
      string s = rec(nums, 0, nums.size(), 10);
      if (s != "") {
        cout << s << endl;
        exist = true;
        break;
      }
    } while (next_permutation(nums.begin(), nums.end()));

    if (!exist) {
      cout << "0" << endl;
    }
  }
  return 0;
}

Error: TLE

Fixed submission:

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

using namespace std;

const int N = 4;
const int MAX_E = 100;
const char ope[] = {'+', '-', '*'};

bool is_end(vector<int> a) {
  REP(i, a.size()) if (a[i] != 0) return false;
  return true;
}

int calc(int type, int val, int x) {
  if (type == 0)
    return val - x;
  if (type == 1)
    return x - val;
  if (type == 2)
    return val / x;
}

bool used[5][5][300];
string memo[5][5][300];
string rec(const vector<int> &nums, int l, int r, int val) {
  if (used[l][r][val + MAX_E])
    return memo[l][r][val + MAX_E];
  used[l][r][val + MAX_E] = true;
  string &res = memo[l][r][val + MAX_E];

  if (r - l == 1) {
    if (nums[l] == val) {
      return res = to_string(val);
    } else {
      return res = "";
    }
  }

  for (int k = 1; l + k < r; k++) {
    for (int x = -MAX_E; x <= MAX_E; x++) {
      for (int type = 0; type < 3; type++) {
        if (type == 2 && (x == 0 || val % x != 0))
          continue;
        int y = calc(type, val, x);
        string ls = rec(nums, l, l + k, x);
        string rs = rec(nums, l + k, r, y);
        if (ls == "")
          continue;
        if (rs == "")
          continue;
        if (nums.size() == 4)
          return res = "(" + ls + ope[type] + rs + ")";
      }
    }
  }

  return res = "";
}

int main() {
  while (true) {
    vector<int> nums(N);
    REP(i, N) cin >> nums[i];
    if (is_end(nums))
      break;

    bool exist = false;
    sort(nums.begin(), nums.end());
    do {
      memset(used, 0, sizeof(used));
      string s = rec(nums, 0, nums.size(), 10);
      if (s != "") {
        cout << s << endl;
        exist = true;
        break;
      }
    } while (next_permutation(nums.begin(), nums.end()));

    if (!exist) {
      cout << "0" << endl;
    }
  }
  return 0;
}