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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;
vector<int> primes;
map<vector<int>, int> table;

long long exp(long long b, long long e, long long p) {
  long long ret = 1;
  while (e > 0) {
    if ((e & 1) != 0) {
      ret = (ret * b) % p;
    }
    b = (b * b) % p;
    e >>= 1;
  }
  return ret % p;
}

bool fermat(long long p) {
  if (p <= 1)
    return false;
  if (p != 2 && p % 2 == 0)
    return false;
  if (p != 3 && p % 3 == 0)
    return false;
  if (p != 5 && p % 5 == 0)
    return false;
  if (p != 7 && p % 7 == 0)
    return false;
  if (p != 11 && p % 11 == 0)
    return false;
  if (p != 13 && p % 13 == 0)
    return false;
  for (int x = 0; x < 100; ++x) {
    long long a = rand() % (p - 1) + 1;
    if (exp(a, p - 1, p) != 1)
      return false;
  }
  return true;
}

bool triangle(int a, int b, int c) {
  return a + b > c && a + c > b && b + c > a;
}

int main() {
  primes.clear();
  for (int x = 2; x < 30005; ++x) {
    if (fermat(x))
      primes.push_back(x);
  }
  int n;
  while (scanf("%d", &n) == 1, n) {
    table.clear();
    int s = 0;
    for (int x = 0; x < primes.size(); ++x) {
      if (primes[x] > n)
        break;
      for (int y = x; y < primes.size(); ++y) {
        if (primes[x] + primes[y] >= n)
          break;
        int w = n - primes[x] - primes[y];
        bool t = triangle(w, primes[x], primes[y]);
        if (t && binary_search(primes.begin(), primes.end(), w)) {
          vector<int> tmp;
          tmp.push_back(primes[x]);
          tmp.push_back(primes[y]);
          tmp.push_back(w);
          sort(tmp.begin(), tmp.end());
          table[tmp]++;
        }
      }
    }
    cout << table.size() << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;
vector<int> primes;
map<vector<int>, int> table;

long long exp(long long b, long long e, long long p) {
  long long ret = 1;
  while (e > 0) {
    if ((e & 1) != 0) {
      ret = (ret * b) % p;
    }
    b = (b * b) % p;
    e >>= 1;
  }
  return ret % p;
}

bool fermat(long long p) {
  if (p <= 1)
    return false;
  if (p != 2 && p % 2 == 0)
    return false;
  if (p != 3 && p % 3 == 0)
    return false;
  if (p != 5 && p % 5 == 0)
    return false;
  if (p != 7 && p % 7 == 0)
    return false;
  if (p != 11 && p % 11 == 0)
    return false;
  if (p != 13 && p % 13 == 0)
    return false;
  for (int x = 0; x < 100; ++x) {
    long long a = rand() % (p - 1) + 1;
    if (exp(a, p - 1, p) != 1)
      return false;
  }
  return true;
}

bool triangle(int a, int b, int c) {
  return a + b > c && a + c > b && b + c > a;
}

bool solved(vector<int> sol, int n) {
  if (sol[0] + sol[1] + sol[2] == n) {
    return triangle(sol[0], sol[1], sol[2]);
  }
  return false;
}

void solve(vector<int> sol, int i, int n) {
  if (i == 3 && solved(sol, n)) {
    sort(sol.begin(), sol.end());
    table[sol] = 100;
  } else if (i < 3) {
    int j = 0;
    int stmp = 0;
    for (int x = 0; x < i; ++x) {
      stmp += sol[x];
    }
    while (stmp + primes[j] <= n) {
      sol[i] = primes[j];
      solve(sol, i + 1, n);
      sol[i] = 0;
      ++j;
    }
  }
}

int main() {
  primes.clear();
  for (int x = 2; x < 30005; ++x) {
    if (fermat(x))
      primes.push_back(x);
  }
  int n;
  while (scanf("%d", &n) == 1, n) {
    table.clear();
    for (int x = 0; x < primes.size(); ++x) {
      if (primes[x] > n)
        break;
      for (int y = x; y < primes.size(); ++y) {
        if (primes[x] + primes[y] > n)
          break;
        for (int z = y; z < primes.size(); ++z) {
          long long w = primes[x] + primes[y] + primes[z];
          if (w == n && triangle(primes[x], primes[y], primes[z])) {
            vector<int> tmp;
            tmp.push_back(primes[x]);
            tmp.push_back(primes[y]);
            tmp.push_back(primes[z]);
            sort(tmp.begin(), tmp.end());
            table[tmp] = 100;
          }
          if (w > n)
            break;
        }
      }
    }
    vector<int> sol(3, 0);
    // solve(sol,0,n);
    cout << table.size() << endl;
  }
  return 0;
}