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

#include <algorithm>
#include <chrono>
#include <fstream>
#include <iostream>
#include <map>
#include <random>
#include <string>
#include <vector>
#define tNow                                                                   \\
  chrono::duration_cast<msec>(chrono::system_clock::now().time_since_epoch())
#define INF (1 << 30)
using namespace std;

typedef chrono::milliseconds msec;

int d, lastVal = -INF, bestVal = -INF, times = 0, groups = 0, updates = 0,
       positiveUpdates = 0;
vector<int> c(27), cur, ans;
vector<vector<int>> s;

int calc() {
  int sum = 0;
  vector<int> last(27, 0);
  for (int i = 1; i <= d; ++i) {
    sum += s.at(i).at(cur.at(i));
    last.at(cur.at(i)) = i;
    for (int j = 1; j <= 26; ++j)
      sum -= c.at(j) * (i - last.at(j));
  }
  return sum;
}

void update(int curVal) {
  lastVal = curVal;
  if (bestVal < curVal) {
    bestVal = curVal;
    ans = cur;
    ++positiveUpdates;
  }
  ++updates;
}

int main() {
  random_device r;
  msec st = tNow;
  msec lm = st + chrono::milliseconds(1900);
  cin >> d;
  s = vector<vector<int>>(d + 1, vector<int>(27));
  cur.resize(d + 1);
  for (int i = 1; i <= 26; ++i)
    cin >> c.at(i);
  for (int i = 1; i <= d; ++i)
    for (int j = 1; j <= 26; ++j)
      cin >> s.at(i).at(j);
  mt19937 m(r());
  for (int i = 1; i <= d; ++i)
    cur.at(i) = m() % 26 + 1;
  update(calc());
  // cur = {0, 1, 17, 13, 14, 13};
  // update(calc());
  // cout << bestVal << endl;
  // for (int i = 1; i <= d; ++i) cout << ans.at(i) << endl;

  while (tNow < lm) {
    ++groups;
    mt19937 m(r());
    for (int i = 0; i < 100; ++i) {
      int changeAt = m() % d + 1, changeTo = m() % 26 + 1,
          changedFrom = cur.at(changeAt);
      if (changedFrom == changeTo)
        continue;
      cur.at(changeAt) = changeTo;
      int curVal = calc();
      if (curVal > lastVal)
        update(curVal);
      else
        cur.at(changeAt) = changedFrom;
      ++times;
    }
  }

  for (int i = 1; i <= d; ++i)
    cout << ans.at(i) << endl;
  msec ed = tNow;
#ifdef ___DEBUG
  cout << "Best Value: " << bestVal << endl;
  cout << "Best Score: " << max(bestVal + 1000000, 0) << endl;
  cout << "Tried: " << times << "times, " << groups << "groups\\n";
  cout << "Updated: " << updates << "times\\n";
  cout << (ed - st).count() << "ms\\n";
#endif
  return 0;
}


Error: TLE

Fixed submission:

#include <chrono>
#include <fstream>
#include <iostream>
#include <map>
#include <random>
#include <string>
#include <vector>
#define tNow                                                                   \\
  chrono::duration_cast<msec>(chrono::system_clock::now().time_since_epoch())
#define INF (1 << 30)
using namespace std;

typedef chrono::milliseconds msec;

int d, lastVal = -INF, bestVal = -INF, times = 0, groups = 0, updates = 0,
       positiveUpdates = 0;
vector<int> c(27), cur, ans;
vector<vector<int>> s;

int calc() {
  int sum = 0;
  vector<int> last(27, 0);
  for (int i = 1; i <= d; ++i) {
    sum += s.at(i).at(cur.at(i));
    last.at(cur.at(i)) = i;
    for (int j = 1; j <= 26; ++j)
      sum -= c.at(j) * (i - last.at(j));
  }
  return sum;
}

void update(int curVal) {
  lastVal = curVal;
  if (bestVal < curVal) {
    bestVal = curVal;
    ans = cur;
    ++positiveUpdates;
  }
  ++updates;
}

int main() {
  random_device r;
  msec st = tNow;
  msec lm = st + chrono::milliseconds(1995);
  cin >> d;
  s = vector<vector<int>>(d + 1, vector<int>(27));
  cur.resize(d + 1);
  for (int i = 1; i <= 26; ++i)
    cin >> c.at(i);
  for (int i = 1; i <= d; ++i)
    for (int j = 1; j <= 26; ++j)
      cin >> s.at(i).at(j);
  mt19937 m(r());
  for (int i = 1; i <= d; ++i)
    cur.at(i) = m() % 26 + 1;
  update(calc());
  // cur = {0, 1, 17, 13, 14, 13};
  // update(calc());
  // cout << bestVal << endl;
  // for (int i = 1; i <= d; ++i) cout << ans.at(i) << endl;

  while (tNow < lm) {
    ++groups;
    mt19937 m(r());
    for (int i = 0; i < 100; ++i) {
      int changeAt = m() % d + 1, changeTo = m() % 26 + 1,
          changedFrom = cur.at(changeAt);
      if (changedFrom == changeTo)
        continue;
      cur.at(changeAt) = changeTo;
      int curVal = calc();
      if (curVal > lastVal)
        update(curVal);
      else
        cur.at(changeAt) = changedFrom;
      ++times;
    }
  }

  for (int i = 1; i <= d; ++i)
    cout << ans.at(i) << endl;
  // msec ed = tNow;
  // cout << bestVal << endl;
  // cout << (ed - st).count() << endl;
  // cout << "Tried: " << times << "times, " << groups << "groups\\n";
  // cout << "Updated: " << updates << "times\\n";
  // cout << (ed - st).count() << "ms\\n";
  return 0;
}