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

#include <algorithm>
#include <complex>
#include <cstdio>
#include <deque>
#include <iomanip>
#include <iostream>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <sys/time.h>
#include <vector>

#define REP(i, m, n) for (int i = int(m); i < int(n); i++)
#define RREP(i, m, n) for (int i = int(n) - 1; i >= int(m); --i)
#define EACH(i, c) for (auto &(i) : c)
#define all(c) begin(c), end(c)
#define EXIST(s, e) ((s).find(e) != (s).end())
#define SORT(c) sort(begin(c), end(c))
#define pb emplace_back
#define MP make_pair
#define SZ(a) int((a).size())
// #define int long long

#ifdef LOCAL
#define DEBUG(s) cout << (s) << endl
#define dump(x) cerr << #x << " = " << (x) << endl
#define BR cout << endl;
#else
#define DEBUG(s)                                                               \\
  do {                                                                         \\
  } while (0)
#define dump(x)                                                                \\
  do {                                                                         \\
  } while (0)
#define BR
#endif
using namespace std;

using UI = unsigned int;
using UL = unsigned long;
using LL = long long;
using ULL = unsigned long long;
using VI = vector<int>;
using VVI = vector<VI>;
using VLL = vector<LL>;
using VVLL = vector<VLL>;
using VS = vector<string>;
using PII = pair<int, int>;
using VP = vector<PII>;
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}

template <class T> inline T sqr(T x) { return x * x; }

double diff(timeval &start, timeval &now) {
  return (now.tv_sec - start.tv_sec) +
         (now.tv_usec - start.tv_usec) / 1000000.0;
}

unsigned int xor96(void) {
  static unsigned int x = 123456789;
  static unsigned int y = 362436069;
  static unsigned int z = 521288629;
  unsigned int t;

  t = (x ^ (x << 3)) ^ (y ^ (y >> 19)) ^ (z ^ (z << 6));
  x = y;
  y = z;
  return z = t;
}

class State {
  int d;

public:
  VI contests;
  int score;
  State(const State &rhs)
      : contests(rhs.contests), score(rhs.score), d(rhs.d) {}
  State(const VI &init, int d) : contests(init), d(d) {}
  void init(const VI &c, const VVI &s) { score = calcScore(c, s); }
  int calcScore(const VI &c, const VVI &s) {
    int score = 0;
    VI lasts(26, 0);
    REP(i, 0, d) {
      score += s[i][contests[i]];
      lasts[contests[i]] = i;
      REP(j, 0, 26) { score -= c[j] * (i - lasts[j]); }
    }
    return score;
  }
  State modify(const VI &c, const VVI &s) {
    State newState(*this);

    if (xor96() % 4) {
      unsigned int pos = xor96() % d;
      newState.contests[pos] = xor96() % 26;
    } else {
      // 一カ所ランダムに変える
      unsigned int l = xor96() % d, r = xor96() % d;
      swap(newState.contests[l], newState.contests[r]);
    }
    newState.score = newState.calcScore(c, s);

    return newState;
  }
  void show() {
    REP(i, 0, d) { cout << contests[i] + 1 << endl; }
  }
};

// 焼きなまし法
State sa(int d, VI &c, VVI &s, double start_temp, double end_temp,
         double TIME_LIMIT) {
  VI init(d);
  REP(i, 0, d) init[i] = xor96() % 26;
  State state(init, d);
  state.init(c, s);

  int times = 0;
  struct timeval start_timeval, now_timeval;
  gettimeofday(&start_timeval, NULL);
  gettimeofday(&now_timeval, NULL);
  while (diff(start_timeval, now_timeval) < TIME_LIMIT) { // 時間の許す限り回す
    ++times;
    REP(loop, 0, 100) {
      State new_state = state.modify(c, s);
      int new_score = new_state.score;
      int pre_score = state.score;

      // 温度関数
      double temp = start_temp + (end_temp - start_temp) *
                                     diff(start_timeval, now_timeval) /
                                     TIME_LIMIT;
      // 遷移確率関数(最大化の場合)
      double prob = exp((new_score - pre_score) / temp);

      if (prob >
          (xor96() % 0xffffffffu) / (double)0xffffffffu) { // 確率probで遷移する
        state = new_state;
      }
    }
    gettimeofday(&now_timeval, NULL);
  }
  dump(times);
  return state;
}

void solve() {
  int d;
  cin >> d;
  VI c(26);
  VVI s(d, VI(26));
  REP(i, 0, 26) { cin >> c[i]; }
  REP(i, 0, d) REP(j, 0, 26) cin >> s[i][j];

  int repeat = 4;
  double timelimit = 1.95;
  State state = sa(d, c, s, 50, 10, timelimit / repeat);
  REP(loop, 1, repeat) {
    State newState = sa(d, c, s, 50 + 10 * repeat, 10, timelimit / repeat);
    if (state.score < newState.score)
      state = newState;
    dump(state.score);
  }
  state.show();
  dump(state.score);
}

signed main() {
  solve();

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <complex>
#include <cstdio>
#include <deque>
#include <iomanip>
#include <iostream>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <sys/time.h>
#include <vector>

#define REP(i, m, n) for (int i = int(m); i < int(n); i++)
#define RREP(i, m, n) for (int i = int(n) - 1; i >= int(m); --i)
#define EACH(i, c) for (auto &(i) : c)
#define all(c) begin(c), end(c)
#define EXIST(s, e) ((s).find(e) != (s).end())
#define SORT(c) sort(begin(c), end(c))
#define pb emplace_back
#define MP make_pair
#define SZ(a) int((a).size())
// #define int long long

#ifdef LOCAL
#define DEBUG(s) cout << (s) << endl
#define dump(x) cerr << #x << " = " << (x) << endl
#define BR cout << endl;
#else
#define DEBUG(s)                                                               \\
  do {                                                                         \\
  } while (0)
#define dump(x)                                                                \\
  do {                                                                         \\
  } while (0)
#define BR
#endif
using namespace std;

using UI = unsigned int;
using UL = unsigned long;
using LL = long long;
using ULL = unsigned long long;
using VI = vector<int>;
using VVI = vector<VI>;
using VLL = vector<LL>;
using VVLL = vector<VLL>;
using VS = vector<string>;
using PII = pair<int, int>;
using VP = vector<PII>;
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}

template <class T> inline T sqr(T x) { return x * x; }

double diff(timeval &start, timeval &now) {
  return (now.tv_sec - start.tv_sec) +
         (now.tv_usec - start.tv_usec) / 1000000.0;
}

unsigned int xor96(void) {
  static unsigned int x = 123456789;
  static unsigned int y = 362436069;
  static unsigned int z = 521288629;
  unsigned int t;

  t = (x ^ (x << 3)) ^ (y ^ (y >> 19)) ^ (z ^ (z << 6));
  x = y;
  y = z;
  return z = t;
}

class State {
  int d;

public:
  VI contests;
  int score;
  State(const State &rhs)
      : contests(rhs.contests), score(rhs.score), d(rhs.d) {}
  State(const VI &init, int d) : contests(init), d(d) {}
  void init(const VI &c, const VVI &s) { score = calcScore(c, s); }
  int calcScore(const VI &c, const VVI &s) {
    int score = 0;
    VI lasts(26, 0);
    REP(i, 0, d) {
      score += s[i][contests[i]];
      lasts[contests[i]] = i;
      REP(j, 0, 26) { score -= c[j] * (i - lasts[j]); }
    }
    return score;
  }
  State modify(const VI &c, const VVI &s) {
    State newState(*this);

    // 一カ所ランダムに変える
    unsigned int l = xor96() % d, r = xor96() % d;
    swap(newState.contests[l], newState.contests[r]);
    newState.score = newState.calcScore(c, s);

    return newState;
  }
  void show() {
    REP(i, 0, d) { cout << contests[i] + 1 << endl; }
  }
};

// 焼きなまし法
State sa(int d, VI &c, VVI &s, double start_temp, double end_temp,
         double TIME_LIMIT) {
  VI init(d);
  REP(i, 0, d) init[i] = rand() % 26;
  State state(init, d);
  state.init(c, s);

  int times = 0;
  struct timeval start_timeval, now_timeval;
  gettimeofday(&start_timeval, NULL);
  gettimeofday(&now_timeval, NULL);
  while (diff(start_timeval, now_timeval) < TIME_LIMIT) { // 時間の許す限り回す
    ++times;
    REP(loop, 0, 100) {
      State new_state = state.modify(c, s);
      int new_score = new_state.score;
      int pre_score = state.score;

      // 温度関数
      double temp = start_temp + (end_temp - start_temp) *
                                     diff(start_timeval, now_timeval) /
                                     TIME_LIMIT;
      // 遷移確率関数(最大化の場合)
      double prob = exp((new_score - pre_score) / temp);

      if (prob >
          (xor96() % 0xffffffffu) / (double)0xffffffffu) { // 確率probで遷移する
        state = new_state;
      }
    }
    gettimeofday(&now_timeval, NULL);
  }
  dump(times);
  return state;
}

void solve() {
  int d;
  cin >> d;
  VI c(26);
  VVI s(d, VI(26));
  REP(i, 0, 26) { cin >> c[i]; }
  REP(i, 0, d) REP(j, 0, 26) cin >> s[i][j];

  int repeat = 4;
  double timelimit = 1.995;
  State state = sa(d, c, s, 50, 10, timelimit / repeat);
  REP(loop, 1, repeat) {
    State newState = sa(d, c, s, 50 + 10 * repeat, 10, timelimit / repeat);
    if (state.score < newState.score)
      state = newState;
    dump(state.score);
  }
  state.show();
  dump(state.score);
}

signed main() {
  solve();

  return 0;
}