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

#include <algorithm>
#include <cstdio>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string.h>
#include <string>
using namespace std;

#define REP(i, n) for (int i = 0; i < n; i++)
#define RREP(i, n) for (int i = (n)-1; i >= 0; i--)
#define FOR(i, b, e) for (int i = b; i < e; i++)
#define to_bit(i) static_cast<bitset<8>>(i)
#define INF (1 << 28)
#define int(n)                                                                 \\
  int n;                                                                       \\
  cin >> n;
#define chMax(m, n) m = max(m, n)
#define chMin(m, n) m = min(m, n)

typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> VI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef pair<long long, long long> PLL;
typedef queue<int> QI;
typedef priority_queue<int> maxpq;
typedef priority_queue<int, vector<int>, greater<int>> minpq;

struct edge {
  int to, cost;
};
int gcd(int a, int b) {
  if (a % b == 0) {
    return (b);
  } else {
    return (gcd(b, a % b));
  }
};
int lcm(int m, int n) {
  if ((0 == m) || (0 == n)) {
    return 0;
  }
  return ((m / gcd(m, n)) * n);
};
unsigned long long comb(long n, long m) {
  if (n < m)
    return 0;
  unsigned long long c = 1;
  m = (n - m < m ? n - m : m);
  for (long ns = n - m + 1, ms = 1; ms <= m; ns++, ms++) {
    c *= ns;
    c /= ms;
  }
  return c;
};
int quadratic(int a, int b, int c) {
  return (int)(-b + sqrt(b * b - 4 * a * c)) / 2 * a;
}

void cp(int from[], int to[], int l) { REP(i, l) to[i] = from[i]; };
void cp(string a1[], string a2[], int l) { REP(i, l) a2[i] = a1[i]; };
double sq(double d) { return d * d; };
int sq(int i) { return i * i; };
double sqd(double d) { return d * d; }
double sqdist(int x1, int y1, int x2, int y2) {
  double dx = x1 - x2, dy = y1 - y2;
  return dx * dx + dy * dy;
};
bool inside(int y, int x, int h, int w) {
  return 0 <= y && y <= (h - 1) && 0 <= x && x <= (w - 1);
};

// 線分の交差判定
bool isCross(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {
  // 並行な場合
  int m = (x2 - x1) * (y4 - y3) - (y2 - y1) * (x4 - x3);
  if (m == 0)
    return false;
  // 媒介変数の値が0より大きく1以下なら交差する、これは問題の状況によって変わるかも。
  double r = (double)((y4 - y3) * (x3 - x1) - (x4 - x3) * (y3 - y1)) / m;
  double s = (double)((y2 - y1) * (x3 - x1) - (x2 - x1) * (y3 - y1)) / m;
  return (0 < r && r <= 1 && 0 < s && s <= 1);
};

// 外積の計算 AB CD の内積を求める
int crossProdct(int ax, int ay, int bx, int by, int cx, int cy, int dx,
                int dy) {
  int abx = bx - ax;
  int aby = by - ay;
  int cdx = dx - cx;
  int cdy = dy - cy;
  return abx * cdy - cdx * aby;
};
double crossProdct(double ax, double ay, double bx, double by, double cx,
                   double cy, double dx, double dy) {
  double abx = bx - ax;
  double aby = by - ay;
  double cdx = dx - cx;
  double cdy = dy - cy;
  return abx * cdy - cdx * aby;
};
double innerProduct(double ax, double ay, double bx, double by, double cx,
                    double cy, double dx, double dy) {
  double abx = bx - ax;
  double aby = by - ay;
  double cdx = dx - cx;
  double cdy = dy - cy;
  return abx * cdx + aby * cdy;
};

// 三角形の内部判定 ABCの中にPがあるか判定
bool inTriangle(int ax, int ay, int bx, int by, int cx, int cy, int px,
                int py) {
  int c1 = crossProdct(ax, ay, bx, by, bx, by, px, py);
  int c2 = crossProdct(bx, by, cx, cy, cx, cy, px, py);
  int c3 = crossProdct(cx, cy, ax, ay, ax, ay, px, py);
  return (c1 > 0 && c2 > 0 && c3 > 0) || (c1 < 0 && c2 < 0 && c3 < 0);
};
bool inTriangle(double ax, double ay, double bx, double by, double cx,
                double cy, double px, double py) {
  double c1 = crossProdct(ax, ay, bx, by, bx, by, px, py);
  double c2 = crossProdct(bx, by, cx, cy, cx, cy, px, py);
  double c3 = crossProdct(cx, cy, ax, ay, ax, ay, px, py);
  return (c1 > 0 && c2 > 0 && c3 > 0) || (c1 < 0 && c2 < 0 && c3 < 0);
};

// 三角形の外心
void circumcenter(double x1, double y1, double x2, double y2, double x3,
                  double y3, double res[3]) {
  double xp1 = (y1 - y3) * (y1 * y1 - y2 * y2 + x1 * x1 - x2 * x2) -
               (y1 - y2) * (y1 * y1 - y3 * y3 + x1 * x1 - x3 * x3);
  double xp2 = 2 * (y1 - y3) * (x1 - x2) - 2 * (y1 - y2) * (x1 - x3);
  res[0] = xp1 / xp2;
  double yp1 = (x1 - x3) * (x1 * x1 - x2 * x2 + y1 * y1 - y2 * y2) -
               (x1 - x2) * (x1 * x1 - x3 * x3 + y1 * y1 - y3 * y3);
  double yp2 = 2 * (x1 - x3) * (y1 - y2) - 2 * (x1 - x2) * (y1 - y3);
  res[1] = yp1 / yp2;
  double r = (x3 - res[0]) * (x3 - res[0]) + (y3 - res[1]) * (y3 - res[1]);
  res[2] = sqrt(r);
}

/**
 * start
 * @author yoshikyoto
 */

int digit(int n, int d) { return (n / (int)pow(10, d)) % 10; }

int main(int argc, const char *argv[]) {
  while (true) {
    int n;
    cin >> n;
    if (!n)
      break;

    int cnt = 0;
    for (int i = 1; i * i <= n; i++) {
      int nn = n - i * i;
      if (nn == 0) {
        cnt++;
        break;
      }
      for (int j = i; j * j <= nn; j++) {
        int nnn = nn - j * j;
        if (nnn == 0) {
          cnt++;
          break;
        }
        for (int k = j; k * k <= nnn; k++) {
          int nnnn = nnn - k * k;
          if (nnnn == 0) {
            cnt++;
            break;
          }
          for (int l = k; l * l <= nnnn; l++) {
            if (nnnn == l * l) {
              cnt++;
              break;
            }
          }
        }
      }
    }
    cout << cnt << endl;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string.h>
#include <string>
using namespace std;

#define REP(i, n) for (int i = 0; i < n; i++)
#define RREP(i, n) for (int i = (n)-1; i >= 0; i--)
#define FOR(i, b, e) for (int i = b; i < e; i++)
#define to_bit(i) static_cast<bitset<8>>(i)
#define INF (1 << 28)
#define int(n)                                                                 \\
  int n;                                                                       \\
  cin >> n;
#define chMax(m, n) m = max(m, n)
#define chMin(m, n) m = min(m, n)

typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> VI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef pair<long long, long long> PLL;
typedef queue<int> QI;
typedef priority_queue<int> maxpq;
typedef priority_queue<int, vector<int>, greater<int>> minpq;

struct edge {
  int to, cost;
};
int gcd(int a, int b) {
  if (a % b == 0) {
    return (b);
  } else {
    return (gcd(b, a % b));
  }
};
int lcm(int m, int n) {
  if ((0 == m) || (0 == n)) {
    return 0;
  }
  return ((m / gcd(m, n)) * n);
};
unsigned long long comb(long n, long m) {
  if (n < m)
    return 0;
  unsigned long long c = 1;
  m = (n - m < m ? n - m : m);
  for (long ns = n - m + 1, ms = 1; ms <= m; ns++, ms++) {
    c *= ns;
    c /= ms;
  }
  return c;
};
int quadratic(int a, int b, int c) {
  return (int)(-b + sqrt(b * b - 4 * a * c)) / 2 * a;
}

void cp(int from[], int to[], int l) { REP(i, l) to[i] = from[i]; };
void cp(string a1[], string a2[], int l) { REP(i, l) a2[i] = a1[i]; };
double sq(double d) { return d * d; };
int sq(int i) { return i * i; };
double sqd(double d) { return d * d; }
double sqdist(int x1, int y1, int x2, int y2) {
  double dx = x1 - x2, dy = y1 - y2;
  return dx * dx + dy * dy;
};
bool inside(int y, int x, int h, int w) {
  return 0 <= y && y <= (h - 1) && 0 <= x && x <= (w - 1);
};

// 線分の交差判定
bool isCross(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {
  // 並行な場合
  int m = (x2 - x1) * (y4 - y3) - (y2 - y1) * (x4 - x3);
  if (m == 0)
    return false;
  // 媒介変数の値が0より大きく1以下なら交差する、これは問題の状況によって変わるかも。
  double r = (double)((y4 - y3) * (x3 - x1) - (x4 - x3) * (y3 - y1)) / m;
  double s = (double)((y2 - y1) * (x3 - x1) - (x2 - x1) * (y3 - y1)) / m;
  return (0 < r && r <= 1 && 0 < s && s <= 1);
};

// 外積の計算 AB CD の内積を求める
int crossProdct(int ax, int ay, int bx, int by, int cx, int cy, int dx,
                int dy) {
  int abx = bx - ax;
  int aby = by - ay;
  int cdx = dx - cx;
  int cdy = dy - cy;
  return abx * cdy - cdx * aby;
};
double crossProdct(double ax, double ay, double bx, double by, double cx,
                   double cy, double dx, double dy) {
  double abx = bx - ax;
  double aby = by - ay;
  double cdx = dx - cx;
  double cdy = dy - cy;
  return abx * cdy - cdx * aby;
};
double innerProduct(double ax, double ay, double bx, double by, double cx,
                    double cy, double dx, double dy) {
  double abx = bx - ax;
  double aby = by - ay;
  double cdx = dx - cx;
  double cdy = dy - cy;
  return abx * cdx + aby * cdy;
};

// 三角形の内部判定 ABCの中にPがあるか判定
bool inTriangle(int ax, int ay, int bx, int by, int cx, int cy, int px,
                int py) {
  int c1 = crossProdct(ax, ay, bx, by, bx, by, px, py);
  int c2 = crossProdct(bx, by, cx, cy, cx, cy, px, py);
  int c3 = crossProdct(cx, cy, ax, ay, ax, ay, px, py);
  return (c1 > 0 && c2 > 0 && c3 > 0) || (c1 < 0 && c2 < 0 && c3 < 0);
};
bool inTriangle(double ax, double ay, double bx, double by, double cx,
                double cy, double px, double py) {
  double c1 = crossProdct(ax, ay, bx, by, bx, by, px, py);
  double c2 = crossProdct(bx, by, cx, cy, cx, cy, px, py);
  double c3 = crossProdct(cx, cy, ax, ay, ax, ay, px, py);
  return (c1 > 0 && c2 > 0 && c3 > 0) || (c1 < 0 && c2 < 0 && c3 < 0);
};

// 三角形の外心
void circumcenter(double x1, double y1, double x2, double y2, double x3,
                  double y3, double res[3]) {
  double xp1 = (y1 - y3) * (y1 * y1 - y2 * y2 + x1 * x1 - x2 * x2) -
               (y1 - y2) * (y1 * y1 - y3 * y3 + x1 * x1 - x3 * x3);
  double xp2 = 2 * (y1 - y3) * (x1 - x2) - 2 * (y1 - y2) * (x1 - x3);
  res[0] = xp1 / xp2;
  double yp1 = (x1 - x3) * (x1 * x1 - x2 * x2 + y1 * y1 - y2 * y2) -
               (x1 - x2) * (x1 * x1 - x3 * x3 + y1 * y1 - y3 * y3);
  double yp2 = 2 * (x1 - x3) * (y1 - y2) - 2 * (x1 - x2) * (y1 - y3);
  res[1] = yp1 / yp2;
  double r = (x3 - res[0]) * (x3 - res[0]) + (y3 - res[1]) * (y3 - res[1]);
  res[2] = sqrt(r);
}

/**
 * start
 * @author yoshikyoto
 */

int inf = 32768;
int MAX = 182;
int s[182];
int dp[4][32769];

int dfs(int cnt, int pos, int n) {
  // cout << "dfs " << cnt << " " << pos << " " << n << endl;
  if (n == 0)
    return 1;
  if (cnt >= 4)
    return 0;
  if (s[pos] > n)
    return 0;
  if (pos > 182)
    return 0;
  return dfs(cnt, pos + 1, n) + dfs(cnt + 1, pos, n - s[pos]);
}

int main(int argc, const char *argv[]) {

  REP(i, 4) REP(j, inf + 1) { dp[i][j] = 0; }

  for (int i = 1; i * i <= inf; i++) {
    int ii = i * i;
    dp[0][ii]++;

    for (int j = i; j * j + ii <= inf; j++) {
      int ij = ii + j * j;
      dp[1][ij]++;

      for (int k = j; k * k + ij <= inf; k++) {
        int ijk = ij + k * k;
        dp[2][ijk]++;

        for (int l = k; l * l + ijk <= inf; l++) {
          dp[3][ijk + l * l]++;
        }
      }
    }
  }

  while (true) {
    int n;
    cin >> n;
    int ans = 0;
    REP(i, 4) ans += dp[i][n];
    cout << ans << endl;
  }
}