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

#include <algorithm>
#include <assert.h>
#include <iostream>
#include <math.h>
#include <set>
#include <stdio.h>
#include <string.h>
#include <vector>

using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
static const double EPS = 1e-9;
static const double PI = acos(-1.0);

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define FORIT(it, c)                                                           \\
  for (__typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
#define MEMSET(v, h) memset((v), h, sizeof(v))

int n;
int s[3][20];
int permu[3][6] = {{0, 0, 1, 1, 2, 2}, {1, 2, 0, 2, 0, 1}, {2, 1, 2, 0, 1, 0}};

int can[10][12 * 60 * 60];
int sum[10][12 * 60 * 60 + 2];

bool calc(int start, int interval) {
  REP(i, n) {
    if (sum[i][start + interval + 1] - sum[i][start] == 0) {
      return false;
    }
  }
  return true;
}

int main() {
  MEMSET(sum, 0);
  while (scanf("%d", &n), n) {
    MEMSET(can, 0);
    set<int> candidate;
    REP(i, n) {
      scanf("%d %d %d", &s[0][i], &s[1][i], &s[2][i]);
      REP(degree, 60) {
        REP(p, 6) {
          int hour = (s[permu[0][p]][i] + degree) % 60;
          int minute = (s[permu[1][p]][i] + degree) % 60;
          int second = (s[permu[2][p]][i] + degree) % 60;
          if (hour % 5 != minute / 12) {
            continue;
          }
          hour /= 5;
          int t = hour * 3600 + minute * 60 + second;
          candidate.insert(t);
          can[i][t] = 1;
        }
      }
    }
    REP(i, n) {
      REP(t, 12 * 60 * 60) { sum[i][t + 1] = sum[i][t] + can[i][t]; }
    }
    int s = -1;
    int l = 0;
    int r = 12 * 60 * 60;
    while (l != r) {
      int m = (l + r) / 2;
      FORIT(it, candidate) {
        if (*it + m >= 12 * 60 * 60) {
          break;
        }
        if (calc(*it, m)) {
          s = *it;
          r = m;
          goto next;
        }
      }
      l = m + 1;
    next:;
    }
    printf("%02d:%02d:%02d %02d:%02d:%02d\\n", s / 3600, s / 60 % 60, s % 60,
           (s + l) / 3600, (s + l) / 60 % 60, (s + l) % 60);
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <assert.h>
#include <iostream>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <vector>

using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
static const double EPS = 1e-9;
static const double PI = acos(-1.0);

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define FORIT(it, c)                                                           \\
  for (__typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
#define MEMSET(v, h) memset((v), h, sizeof(v))

int n;
int s[3][20];
int permu[3][6] = {{0, 0, 1, 1, 2, 2}, {1, 2, 0, 2, 0, 1}, {2, 1, 2, 0, 1, 0}};

int can[20][12 * 60 * 60];
int sum[20][12 * 60 * 60 + 2];

bool calc(int start, int interval) {
  REP(i, n) {
    if (sum[i][start + interval + 1] - sum[i][start] == 0) {
      return false;
    }
  }
  return true;
}

int main() {
  MEMSET(sum, 0);
  while (scanf("%d", &n), n) {
    MEMSET(can, 0);
    REP(i, n) {
      scanf("%d %d %d", &s[0][i], &s[1][i], &s[2][i]);
      REP(degree, 60) {
        REP(p, 6) {
          int hour = (s[permu[0][p]][i] + degree) % 60;
          int minute = (s[permu[1][p]][i] + degree) % 60;
          int second = (s[permu[2][p]][i] + degree) % 60;
          if (hour % 5 != minute / 12) {
            continue;
          }
          hour /= 5;
          int t = hour * 3600 + minute * 60 + second;
          can[i][t] = 1;
        }
      }
    }
    REP(i, n) {
      REP(t, 12 * 60 * 60) { sum[i][t + 1] = sum[i][t] + can[i][t]; }
    }
    int l = 0;
    int r = 12 * 60 * 60;
    while (l != r) {
      int m = (l + r) / 2;
      REP(i, 12 * 60 * 60) {
        if (i + m >= 12 * 60 * 60) {
          l = m + 1;
          break;
        }
        if (calc(i, m)) {
          r = m;
          break;
        }
      }
    }
    int s = -1;
    REP(i, 12 * 60 * 60) {
      if (calc(i, l)) {
        s = i;
        break;
      }
    }
    printf("%02d:%02d:%02d %02d:%02d:%02d\\n", s / 3600, s / 60 % 60, s % 60,
           (s + l) / 3600, (s + l) / 60 % 60, (s + l) % 60);
  }
}