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

#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;

#define CONTEST 26
#define D 365
#define INF 366

int C[CONTEST];
int S[D + 1][CONTEST];

/////////////////////////////////////////////////////////////////////////
// TIME MANAGEMENT
/////////////////////////////////////////////////////////////////////////
// const double TIME_LIMIT = 100;
const double TIME_LIMIT = 1920;
// const double TIME_LIMIT = 19000;
struct TimeManager {
  double lim;
  double elapsed;
  chrono::system_clock::time_point t_start;

  TimeManager() {
    t_start = chrono::system_clock::now();
    lim = TIME_LIMIT;
  }

  template <typename T> TimeManager(const T &t) {
    t_start = chrono::system_clock::now();
    lim = static_cast<double>(t);
  }

  void set_time() { t_start = chrono::system_clock::now(); }

  void update() {
    auto t_now = chrono::system_clock::now();
    elapsed =
        chrono::duration_cast<chrono::milliseconds>(t_now - t_start).count();
  }

  bool is_timeover() { return elapsed > lim; }

  double passed_ratio() {
    // update();
    return elapsed / lim;
  }

  template <typename T> bool is_passed(const T &r) {
    double tmp = static_cast<double>(r);
    return tmp > passed_ratio();
  }
};

TimeManager t_manager;
/////////////////////////////////////////////////////////////////////////
// TIME MANAGEMENT END
/////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////
// XORSHIFT
/////////////////////////////////////////////////////////////////////////
int xorShift() {
  static unsigned long long x = 88172645463325252ULL;
  x ^= x << 13;
  x ^= x >> 7;
  x ^= x << 17;
  return int(x & 0x7fffffff);
}
/////////////////////////////////////////////////////////////////////////
// XORSHIFT END
/////////////////////////////////////////////////////////////////////////

int cur_score = 0, best_score = 0;
int cur_schedule[D + 1], best_schedule[D + 1];
int score_col[CONTEST];
int score_col_old[CONTEST];
int idx2pos[CONTEST][D + 2];
int idx_num[CONTEST];
int pos2idx[CONTEST][D + 2];
long long changed_col[CONTEST];
int siz_cc;
int changed_col2[CONTEST];
int siz_ca;
int changed_at[CONTEST];
int changed_to_col[CONTEST];
int changed_to_col_rev[CONTEST];

int update_ = 0;
bool updateBest() {
  if (best_score >= cur_score)
    return false;
  best_score = cur_score;
  for (int i = 1; i <= D; i++)
    best_schedule[i] = cur_schedule[i];
  update_++;
  return true;
}
bool updateBest(const int &siz, int at[], int col[]) {
  if (best_score >= cur_score)
    return false;
  best_score = cur_score;
  for (int i = 0; i < siz; i++)
    best_schedule[at[i]] = cur_schedule[at[i]];
  // for (int i = 1; i <= D; i++) {
  //   if (best_schedule[i] != cur_schedule[i]) {
  //     for (int j = 1; j <= D; j++) cerr << j << " " << best_schedule[j] << "
  //     " << cur_schedule[j] << " " << (best_schedule[i] == cur_schedule[i] ?
  //     "SAME" : "DIF") << endl;
  //   }
  //   assert(best_schedule[i] == cur_schedule[i]);
  // }
  update_++;
  return true;
}

bool change(const int &at, const int &col) {
  int rem = cur_schedule[at];
  if (rem == col)
    return false;
  assert(col != -1);

  if (rem >= 0) {
    int rem_idx = pos2idx[rem][at];
    pos2idx[rem][at] = -1;
    for (int i = rem_idx + 1; i < idx_num[rem]; i++) {
      idx2pos[rem][i - 1] = idx2pos[rem][i];
      pos2idx[rem][idx2pos[rem][i - 1]] = i - 1;
    }
    idx2pos[rem][idx_num[rem] - 1] = INF;
    idx_num[rem]--;
  }

  if (idx2pos[col][idx_num[col] - 1] < at) {
    idx2pos[col][idx_num[col]] = at;
    pos2idx[col][at] = idx_num[col];
  } else {
    int idx =
        lower_bound(idx2pos[col], idx2pos[col] + D + 2, at) - idx2pos[col];
    assert(at != idx2pos[col][idx]);
    for (int i = idx_num[col]; i > idx; i--) {
      idx2pos[col][i] = idx2pos[col][i - 1];
      pos2idx[col][idx2pos[col][i]] = i;
    }
    idx2pos[col][idx] = at;
    pos2idx[col][at] = idx;
  }
  idx_num[col]++;
  cur_schedule[at] = col;
  return true;
}

int d;
int calcScore() {
  int res = 0;
  for (int col = 0; col < CONTEST; col++) {
    int &score = score_col[col];
    score = 0;
    for (int i = 1; i < idx_num[col]; i++) {
      if (idx2pos[col][i] <= D && idx2pos[col][i] >= 1) {
        score += S[idx2pos[col][i]][col];
      }
      d = idx2pos[col][i] - idx2pos[col][i - 1];
      score -= C[col] * d * (d - 1) / 2;
    }
    res += score;
  }
  return res;
}
int calcScore(const int &base_score) {
  int res = base_score;
  for (int i = 0; i < siz_cc; i++) {
    int &col = changed_col2[i];
    int &score = score_col[col];
    res -= score;
    score = 0;
    for (int j = 1; j < idx_num[col]; j++) {
      score += S[idx2pos[col][i]][col];
      d = idx2pos[col][i] - idx2pos[col][i - 1];
      score -= C[col] * d * (d - 1) / 2;
    }
    res += score;
  }
  return res;
}
int calcScore(const int &base_score, const int &siz, const int &at,
              const int &col) {
  assert(siz == 1);
  int res = base_score;
  int rem = cur_schedule[at];
  {
    int idx = pos2idx[rem][at];
    int &score = score_col[rem];
    res -= score;
    d = idx2pos[rem][idx] - idx2pos[rem][idx - 1];
    score += C[rem] * d * (d - 1) / 2;
    d = idx2pos[rem][idx + 1] - idx2pos[rem][idx];
    score += C[rem] * d * (d - 1) / 2;
    d = idx2pos[rem][idx + 1] - idx2pos[rem][idx - 1];
    score -= C[rem] * d * (d - 1) / 2;
    score -= S[at][rem];
    res += score;
  }
  {
    int idx =
        lower_bound(idx2pos[col], idx2pos[col] + D + 2, at) - idx2pos[col];
    int &score = score_col[col];
    res -= score;
    d = idx2pos[col][idx] - idx2pos[col][idx - 1];
    score += C[col] * d * (d - 1) / 2;
    d = idx2pos[col][idx] - at;
    score -= C[col] * d * (d - 1) / 2;
    d = at - idx2pos[col][idx - 1];
    score -= C[col] * d * (d - 1) / 2;
    score += S[at][col];
    res += score;
  }
  return res;
}

long long try_change_ = 0;
int tryChange(const int &siz, int at[], int col[]) {
  try_change_++;
  int res = cur_score;
  int siz_cc = 0;
  for (int i = 0; i < siz; i++) {
    changed_to_col_rev[i] = cur_schedule[at[i]];
    res = calcScore(res, 1, at[i], col[i]);
    if (changed_col[cur_schedule[at[i]]] != try_change_) {
      score_col_old[cur_schedule[at[i]]] = score_col[cur_schedule[at[i]]];
      changed_col[cur_schedule[at[i]]] = try_change_;
      changed_col2[siz_cc++] = cur_schedule[at[i]];
    }
    if (changed_col[col[i]] != try_change_) {
      score_col_old[col[i]] = score_col[col[i]];
      changed_col[col[i]] = try_change_;
      changed_col2[siz_cc++] = col[i];
    }
    change(at[i], col[i]);
  }
  return res;
}
bool rollBack(const int &siz, int at[], int col[], const int &old_score) {
  cur_score = old_score;
  for (int i = 0; i < siz_cc; i++)
    score_col[changed_col2[i]] = score_col_old[changed_col2[i]];
  for (int i = 0; i < siz; i++)
    change(at[i], col[i]);
  return true;
}

double start_temp;
double end_temp;
int changed_ = 0;
bool SA(const int &nxt_score, const int &old_score) {
  if (old_score <= nxt_score) {
    changed_++;
    return true;
  }

  double temp = start_temp + (end_temp - start_temp) * t_manager.passed_ratio();
  double prob = exp((double)(nxt_score - old_score) / temp);

  if (prob > (double)(xorShift() % 100) / 100) {
    changed_++;
    return true;
  }
  return false;
}

int step = 0;
int replace_ = 0;
bool replaceAccept(const int &at, const int &col) {
  return cur_schedule[at] != col;
}
bool replace() {
  step++;
  int at = xorShift() % D + 1;
  int col = xorShift() % CONTEST;
  for (int i = 0; i < 5 && !replaceAccept(at, col); i++) {
    at = xorShift() % D + 1;
    col = xorShift() % CONTEST;
  }
  if (!replaceAccept(at, col))
    return false;

  int old_score = cur_score;
  siz_ca = 1;
  changed_at[0] = at;
  changed_to_col[0] = col;
  int new_score = tryChange(siz_ca, changed_at, changed_to_col);
  if (SA(new_score, old_score)) {
    cur_score = new_score;
    // updateBest(siz_ca, changed_at, changed_to_col);
    // updateBest();
    replace_++;
    return true;
  } else {
    rollBack(siz_ca, changed_at, changed_to_col_rev, old_score);
    return false;
  }
}

int shift_ = 0;
bool shift() {
  step++;
  int at = xorShift() % D + 1;
  int col = cur_schedule[at];
  int pre_at = idx2pos[col][pos2idx[col][at] - 1];
  for (int i = max(1, at - 15); i < at; i++)
    if (cur_schedule[i] != col) {
      siz_ca = 0;
      changed_at[siz_ca] = at;
      changed_to_col[siz_ca] = cur_schedule[i];
      siz_ca++;
      changed_at[siz_ca] = i;
      changed_to_col[siz_ca] = col;
      siz_ca++;
      int old_score = cur_score;
      int new_score = tryChange(siz_ca, changed_at, changed_to_col);
      if (SA(new_score, old_score)) {
        cur_score = new_score;
        // updateBest(siz_ca, changed_at, changed_to_col);
        // updateBest();
        shift_++;
        return true;
      } else {
        rollBack(siz_ca, changed_at, changed_to_col_rev, old_score);
      }
    }

  // return false;

  int cnt = 0;
  pre_at = max(pre_at, at - 5);
  for (int i = pre_at + 1; i < at; i++)
    if (cur_schedule[i] != col) {
      int col2 = cur_schedule[i];
      int pre_at2 = idx2pos[col2][pos2idx[col2][i] - 1];
      pre_at2 = max(pre_at2, pre_at - 5);
      for (int j = pre_at2 + 1; j < pre_at; j++)
        if (cur_schedule[i] != cur_schedule[j] && cur_schedule[j] != col) {
          siz_ca = 0;
          changed_at[siz_ca] = at;
          changed_to_col[siz_ca] = cur_schedule[j];
          siz_ca++;
          changed_at[siz_ca] = i;
          changed_to_col[siz_ca] = col;
          siz_ca++;
          changed_at[siz_ca] = j;
          changed_to_col[siz_ca] = cur_schedule[i];
          siz_ca++;
          int old_score = cur_score;
          int new_score = tryChange(siz_ca, changed_at, changed_to_col);
          if (SA(new_score, old_score)) {
            cur_score = new_score;
            // updateBest(siz_ca, changed_at, changed_to_col);
            // updateBest();
            shift_++;
            return true;
          } else {
            rollBack(siz_ca, changed_at, changed_to_col_rev, old_score);
          }
          cnt++;
        }
    }
  return false;
}

int perm[4];
int perm_ = 0;
bool changePermAccept(const int &st) { return st <= 362; }
bool changePerm() {
  int st = xorShift() % D + 1;
  for (int i = 0; i < 10 && !changePermAccept(st); i++) {
    st = xorShift() % D + 1;
  }
  if (!changePermAccept(st))
    return false;
  // for (int i = 0; i < 4; i++) {
  //   perm[i] = i;
  // }
  perm[0] = 0;
  perm[1] = 1;
  perm[2] = 3;
  perm[3] = 2;

  int old_score = cur_score;
  do {
    siz_ca = 0;
    for (int i = 0; i < 4; i++) {
      changed_at[i] = i + st;
      changed_to_col[i] = cur_schedule[perm[i] + st];
      siz_ca++;
    }
    int new_score = tryChange(siz_ca, changed_at, changed_to_col);
    if (SA(new_score, old_score)) {
      cur_score = new_score;
      updateBest();
      perm_++;
      return true;
    } else {
      rollBack(siz_ca, changed_at, changed_to_col_rev, old_score);
    }
  } while (next_permutation(perm, perm + 4));

  return true;

  perm[0] = 0;
  perm[1] = 1;
  perm[2] = 2;
  perm[3] = 3;
  old_score = cur_score;
  while (next_permutation(perm, perm + 4)) {
    siz_ca = 0;
    for (int i = 0; i < 4; i++) {
      changed_at[i] = i + st;
      if (i == 2)
        changed_to_col[i] = xorShift() % CONTEST;
      else
        changed_to_col[i] = cur_schedule[perm[i] + st];
      siz_ca++;
    }
    int new_score = tryChange(siz_ca, changed_at, changed_to_col);
    if (SA(new_score, old_score)) {
      cur_score = new_score;
      updateBest(siz_ca, changed_at, changed_to_col);
      perm_++;
      return true;
    } else {
      rollBack(siz_ca, changed_at, changed_to_col_rev, old_score);
    }
  }

  return false;
}

void initializer() {
  for (int i = 1; i <= D; i++) {
    int val = -1;
    int idx = -1;
    for (int j = 0; j < CONTEST; j++) {
      if (val < S[i][j]) {
        val = S[i][j];
        idx = j;
      }
    }
    assert(idx != -1);
    change(i, idx);
  }
}

void init() {
  int t;
  cin >> t;

  for (int i = 0; i <= D; i++)
    cur_schedule[i] = best_schedule[i] = -1;
  for (int i = 0; i < CONTEST; i++) {
    idx2pos[i][idx_num[i]++] = 0;
    idx2pos[i][idx_num[i]++] = INF;
    for (int j = 2; j < D + 2; j++)
      idx2pos[i][j] = INF;
  }
  for (int i = 0; i < CONTEST; i++)
    cin >> C[i];
  for (int i = 1; i <= D; i++) {
    for (int j = 0; j < CONTEST; j++) {
      cin >> S[i][j];
    }
  }
  initializer();
  cur_score = calcScore();
  best_score = -(1e9);
  updateBest();
  start_temp = (double)abs(cur_score) / 5e5;
  end_temp = 0;
  t_manager.update();
}

void output() {
  for (int i = 1; i <= D; i++) {
    assert(cur_schedule[i] >= 0 && cur_schedule[i] <= 25);
    cout << cur_schedule[i] + 1 << endl;
  }
}

void displeyInfo() {
  cerr << endl;
  cerr << "cur_score = " << cur_score << endl;
  cerr << "best_score = " << best_score << endl;
  cerr << "step = " << step << endl;
  cerr << "changed = " << changed_ << endl;
  cerr << "replace = " << replace_ << endl;
  cerr << "shift = " << shift_ << endl;
  cerr << "perm = " << perm_ << endl;
  cerr << "time passed = " << setprecision(3) << fixed
       << t_manager.passed_ratio() << endl;
  cerr << endl;
}

int naiveCalc() {
  int res = 0;
  for (int i = 1; i <= D; i++) {
    for (int j = 0; j < CONTEST; j++) {
      if (j == cur_schedule[i]) {
        res += S[i][j];
      }
      int k = 0;
      for (int l = 1; l <= i; l++)
        if (cur_schedule[l] == j)
          k = l;
      res -= C[j] * (i - k);
    }
    // cout << res << endl;
  }
  return res;
}

int naiveCalcBest() {
  int res = 0;
  for (int i = 1; i <= D; i++) {
    for (int j = 0; j < CONTEST; j++) {
      if (j == best_schedule[i]) {
        res += S[i][j];
      }
      int k = 0;
      for (int l = 1; l <= i; l++)
        if (best_schedule[l] == j)
          k = l;
      res -= C[j] * (i - k);
    }
    // cout << res << endl;
  }
  return res;
}

signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);

  init();
  displeyInfo();

  bool upd;
  for (int i = 0; !t_manager.is_timeover(); i++) {
    if (i % 255 == 0) {
      t_manager.update();
    }

    upd = false;
    if (!upd)
      upd |= shift();
    if (!upd)
      upd |= replace();

    if (t_manager.passed_ratio() > 0.7)
      updateBest();

    // if (i % 1000 == 0) {
    //   int get = naiveCalcBest();
    //   if (get != best_score) {
    //     cerr << "i = " << i << " get = " << get << " best_score = " <<
    //     best_score << endl; int get2 = naiveCalc(); cerr << "get2 = " << get2
    //     << " cur_score = " << cur_score << endl;
    //   }
    //   assert(get == best_score);
    // }

    // if (i % 5000 == 0) {
    //   displeyInfo();
    // }
  }

  output();
  displeyInfo();
  return 0;
}

Error: TLE

Fixed submission:

#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;

#define CONTEST 26
#define D 365
#define INF 366

int C[CONTEST];
int S[D + 1][CONTEST];

/////////////////////////////////////////////////////////////////////////
// TIME MANAGEMENT
/////////////////////////////////////////////////////////////////////////
// const double TIME_LIMIT = 100;
// const double TIME_LIMIT = 1920;
const double TIME_LIMIT = 19000;
struct TimeManager {
  double lim;
  double elapsed;
  chrono::system_clock::time_point t_start;

  TimeManager() {
    t_start = chrono::system_clock::now();
    lim = TIME_LIMIT;
  }

  template <typename T> TimeManager(const T &t) {
    t_start = chrono::system_clock::now();
    lim = static_cast<double>(t);
  }

  void set_time() { t_start = chrono::system_clock::now(); }

  void update() {
    auto t_now = chrono::system_clock::now();
    elapsed =
        chrono::duration_cast<chrono::milliseconds>(t_now - t_start).count();
  }

  bool is_timeover() { return elapsed > lim; }

  double passed_ratio() {
    // update();
    return elapsed / lim;
  }

  template <typename T> bool is_passed(const T &r) {
    double tmp = static_cast<double>(r);
    return tmp > passed_ratio();
  }
};

TimeManager t_manager;
/////////////////////////////////////////////////////////////////////////
// TIME MANAGEMENT END
/////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////
// XORSHIFT
/////////////////////////////////////////////////////////////////////////
int xorShift() {
  static unsigned long long x = 88172645463325252ULL;
  x ^= x << 13;
  x ^= x >> 7;
  x ^= x << 17;
  return int(x & 0x7fffffff);
}
/////////////////////////////////////////////////////////////////////////
// XORSHIFT END
/////////////////////////////////////////////////////////////////////////

int cur_score = 0, best_score = 0;
int cur_schedule[D + 1], best_schedule[D + 1];
int score_col[CONTEST];
int score_col_old[CONTEST];
int idx2pos[CONTEST][D + 2];
int idx_num[CONTEST];
int pos2idx[CONTEST][D + 2];
long long changed_col[CONTEST];
int siz_cc;
int changed_col2[CONTEST];
int siz_ca;
int changed_at[CONTEST];
int changed_to_col[CONTEST];
int changed_to_col_rev[CONTEST];

int update_ = 0;
bool updateBest() {
  if (best_score >= cur_score)
    return false;
  best_score = cur_score;
  for (int i = 1; i <= D; i++)
    best_schedule[i] = cur_schedule[i];
  update_++;
  return true;
}
bool updateBest(const int &siz, int at[], int col[]) {
  if (best_score >= cur_score)
    return false;
  best_score = cur_score;
  for (int i = 0; i < siz; i++)
    best_schedule[at[i]] = cur_schedule[at[i]];
  // for (int i = 1; i <= D; i++) {
  //   if (best_schedule[i] != cur_schedule[i]) {
  //     for (int j = 1; j <= D; j++) cerr << j << " " << best_schedule[j] << "
  //     " << cur_schedule[j] << " " << (best_schedule[i] == cur_schedule[i] ?
  //     "SAME" : "DIF") << endl;
  //   }
  //   assert(best_schedule[i] == cur_schedule[i]);
  // }
  update_++;
  return true;
}

bool change(const int &at, const int &col) {
  int rem = cur_schedule[at];
  if (rem == col)
    return false;
  assert(col != -1);

  if (rem >= 0) {
    int rem_idx = pos2idx[rem][at];
    pos2idx[rem][at] = -1;
    for (int i = rem_idx + 1; i < idx_num[rem]; i++) {
      idx2pos[rem][i - 1] = idx2pos[rem][i];
      pos2idx[rem][idx2pos[rem][i - 1]] = i - 1;
    }
    idx2pos[rem][idx_num[rem] - 1] = INF;
    idx_num[rem]--;
  }

  if (idx2pos[col][idx_num[col] - 1] < at) {
    idx2pos[col][idx_num[col]] = at;
    pos2idx[col][at] = idx_num[col];
  } else {
    int idx =
        lower_bound(idx2pos[col], idx2pos[col] + D + 2, at) - idx2pos[col];
    assert(at != idx2pos[col][idx]);
    for (int i = idx_num[col]; i > idx; i--) {
      idx2pos[col][i] = idx2pos[col][i - 1];
      pos2idx[col][idx2pos[col][i]] = i;
    }
    idx2pos[col][idx] = at;
    pos2idx[col][at] = idx;
  }
  idx_num[col]++;
  cur_schedule[at] = col;
  return true;
}

int d;
int calcScore() {
  int res = 0;
  for (int col = 0; col < CONTEST; col++) {
    int &score = score_col[col];
    score = 0;
    for (int i = 1; i < idx_num[col]; i++) {
      if (idx2pos[col][i] <= D && idx2pos[col][i] >= 1) {
        score += S[idx2pos[col][i]][col];
      }
      d = idx2pos[col][i] - idx2pos[col][i - 1];
      score -= C[col] * d * (d - 1) / 2;
    }
    res += score;
  }
  return res;
}
int calcScore(const int &base_score) {
  int res = base_score;
  for (int i = 0; i < siz_cc; i++) {
    int &col = changed_col2[i];
    int &score = score_col[col];
    res -= score;
    score = 0;
    for (int j = 1; j < idx_num[col]; j++) {
      score += S[idx2pos[col][i]][col];
      d = idx2pos[col][i] - idx2pos[col][i - 1];
      score -= C[col] * d * (d - 1) / 2;
    }
    res += score;
  }
  return res;
}
int calcScore(const int &base_score, const int &siz, const int &at,
              const int &col) {
  assert(siz == 1);
  int res = base_score;
  int rem = cur_schedule[at];
  {
    int idx = pos2idx[rem][at];
    int &score = score_col[rem];
    res -= score;
    d = idx2pos[rem][idx] - idx2pos[rem][idx - 1];
    score += C[rem] * d * (d - 1) / 2;
    d = idx2pos[rem][idx + 1] - idx2pos[rem][idx];
    score += C[rem] * d * (d - 1) / 2;
    d = idx2pos[rem][idx + 1] - idx2pos[rem][idx - 1];
    score -= C[rem] * d * (d - 1) / 2;
    score -= S[at][rem];
    res += score;
  }
  {
    int idx =
        lower_bound(idx2pos[col], idx2pos[col] + D + 2, at) - idx2pos[col];
    int &score = score_col[col];
    res -= score;
    d = idx2pos[col][idx] - idx2pos[col][idx - 1];
    score += C[col] * d * (d - 1) / 2;
    d = idx2pos[col][idx] - at;
    score -= C[col] * d * (d - 1) / 2;
    d = at - idx2pos[col][idx - 1];
    score -= C[col] * d * (d - 1) / 2;
    score += S[at][col];
    res += score;
  }
  return res;
}

long long try_change_ = 0;
int tryChange(const int &siz, int at[], int col[]) {
  try_change_++;
  int res = cur_score;
  int siz_cc = 0;
  for (int i = 0; i < siz; i++) {
    changed_to_col_rev[i] = cur_schedule[at[i]];
    res = calcScore(res, 1, at[i], col[i]);
    if (changed_col[cur_schedule[at[i]]] != try_change_) {
      score_col_old[cur_schedule[at[i]]] = score_col[cur_schedule[at[i]]];
      changed_col[cur_schedule[at[i]]] = try_change_;
      changed_col2[siz_cc++] = cur_schedule[at[i]];
    }
    if (changed_col[col[i]] != try_change_) {
      score_col_old[col[i]] = score_col[col[i]];
      changed_col[col[i]] = try_change_;
      changed_col2[siz_cc++] = col[i];
    }
    change(at[i], col[i]);
  }
  return res;
}
bool rollBack(const int &siz, int at[], int col[], const int &old_score) {
  cur_score = old_score;
  for (int i = 0; i < siz_cc; i++)
    score_col[changed_col2[i]] = score_col_old[changed_col2[i]];
  for (int i = 0; i < siz; i++)
    change(at[i], col[i]);
  return true;
}

double start_temp;
double end_temp;
int changed_ = 0;
bool SA(const int &nxt_score, const int &old_score) {
  if (old_score <= nxt_score) {
    changed_++;
    return true;
  }

  double temp = start_temp + (end_temp - start_temp) * t_manager.passed_ratio();
  double prob = exp((double)(nxt_score - old_score) / temp);

  if (prob > (double)(xorShift() % 100) / 100) {
    changed_++;
    return true;
  }
  return false;
}

int step = 0;
int replace_ = 0;
bool replaceAccept(const int &at, const int &col) {
  return cur_schedule[at] != col;
}
bool replace() {
  step++;
  int at = xorShift() % D + 1;
  int col = xorShift() % CONTEST;
  for (int i = 0; i < 5 && !replaceAccept(at, col); i++) {
    at = xorShift() % D + 1;
    col = xorShift() % CONTEST;
  }
  if (!replaceAccept(at, col))
    return false;

  int old_score = cur_score;
  siz_ca = 1;
  changed_at[0] = at;
  changed_to_col[0] = col;
  int new_score = tryChange(siz_ca, changed_at, changed_to_col);
  if (SA(new_score, old_score)) {
    cur_score = new_score;
    // updateBest(siz_ca, changed_at, changed_to_col);
    // updateBest();
    replace_++;
    return true;
  } else {
    rollBack(siz_ca, changed_at, changed_to_col_rev, old_score);
    return false;
  }
}

int shift_ = 0;
bool shift() {
  step++;
  int at = xorShift() % D + 1;
  int col = cur_schedule[at];
  int pre_at = idx2pos[col][pos2idx[col][at] - 1];
  for (int i = max(1, at - 15); i < at; i++)
    if (cur_schedule[i] != col) {
      siz_ca = 0;
      changed_at[siz_ca] = at;
      changed_to_col[siz_ca] = cur_schedule[i];
      siz_ca++;
      changed_at[siz_ca] = i;
      changed_to_col[siz_ca] = col;
      siz_ca++;
      int old_score = cur_score;
      int new_score = tryChange(siz_ca, changed_at, changed_to_col);
      if (SA(new_score, old_score)) {
        cur_score = new_score;
        // updateBest(siz_ca, changed_at, changed_to_col);
        // updateBest();
        shift_++;
        return true;
      } else {
        rollBack(siz_ca, changed_at, changed_to_col_rev, old_score);
      }
    }

  // return false;

  int cnt = 0;
  pre_at = max(pre_at, at - 5);
  for (int i = pre_at + 1; i < at; i++)
    if (cur_schedule[i] != col) {
      int col2 = cur_schedule[i];
      int pre_at2 = idx2pos[col2][pos2idx[col2][i] - 1];
      pre_at2 = max(pre_at2, pre_at - 5);
      for (int j = pre_at2 + 1; j < pre_at; j++)
        if (cur_schedule[i] != cur_schedule[j] && cur_schedule[j] != col) {
          siz_ca = 0;
          changed_at[siz_ca] = at;
          changed_to_col[siz_ca] = cur_schedule[j];
          siz_ca++;
          changed_at[siz_ca] = i;
          changed_to_col[siz_ca] = col;
          siz_ca++;
          changed_at[siz_ca] = j;
          changed_to_col[siz_ca] = cur_schedule[i];
          siz_ca++;
          int old_score = cur_score;
          int new_score = tryChange(siz_ca, changed_at, changed_to_col);
          if (SA(new_score, old_score)) {
            cur_score = new_score;
            // updateBest(siz_ca, changed_at, changed_to_col);
            // updateBest();
            shift_++;
            return true;
          } else {
            rollBack(siz_ca, changed_at, changed_to_col_rev, old_score);
          }
          cnt++;
        }
    }
  return false;
}

int perm[4];
int perm_ = 0;
bool changePermAccept(const int &st) { return st <= 362; }
bool changePerm() {
  int st = xorShift() % D + 1;
  for (int i = 0; i < 10 && !changePermAccept(st); i++) {
    st = xorShift() % D + 1;
  }
  if (!changePermAccept(st))
    return false;
  // for (int i = 0; i < 4; i++) {
  //   perm[i] = i;
  // }
  perm[0] = 0;
  perm[1] = 1;
  perm[2] = 3;
  perm[3] = 2;

  int old_score = cur_score;
  do {
    siz_ca = 0;
    for (int i = 0; i < 4; i++) {
      changed_at[i] = i + st;
      changed_to_col[i] = cur_schedule[perm[i] + st];
      siz_ca++;
    }
    int new_score = tryChange(siz_ca, changed_at, changed_to_col);
    if (SA(new_score, old_score)) {
      cur_score = new_score;
      updateBest();
      perm_++;
      return true;
    } else {
      rollBack(siz_ca, changed_at, changed_to_col_rev, old_score);
    }
  } while (next_permutation(perm, perm + 4));

  return true;

  perm[0] = 0;
  perm[1] = 1;
  perm[2] = 2;
  perm[3] = 3;
  old_score = cur_score;
  while (next_permutation(perm, perm + 4)) {
    siz_ca = 0;
    for (int i = 0; i < 4; i++) {
      changed_at[i] = i + st;
      if (i == 2)
        changed_to_col[i] = xorShift() % CONTEST;
      else
        changed_to_col[i] = cur_schedule[perm[i] + st];
      siz_ca++;
    }
    int new_score = tryChange(siz_ca, changed_at, changed_to_col);
    if (SA(new_score, old_score)) {
      cur_score = new_score;
      updateBest(siz_ca, changed_at, changed_to_col);
      perm_++;
      return true;
    } else {
      rollBack(siz_ca, changed_at, changed_to_col_rev, old_score);
    }
  }

  return false;
}

void initializer() {
  for (int i = 1; i <= D; i++) {
    int val = -1;
    int idx = -1;
    for (int j = 0; j < CONTEST; j++) {
      if (val < S[i][j]) {
        val = S[i][j];
        idx = j;
      }
    }
    assert(idx != -1);
    change(i, idx);
  }
}

void init() {
  int t;
  cin >> t;

  for (int i = 0; i <= D; i++)
    cur_schedule[i] = best_schedule[i] = -1;
  for (int i = 0; i < CONTEST; i++) {
    idx2pos[i][idx_num[i]++] = 0;
    idx2pos[i][idx_num[i]++] = INF;
    for (int j = 2; j < D + 2; j++)
      idx2pos[i][j] = INF;
  }
  for (int i = 0; i < CONTEST; i++)
    cin >> C[i];
  for (int i = 1; i <= D; i++) {
    for (int j = 0; j < CONTEST; j++) {
      cin >> S[i][j];
    }
  }
  initializer();
  cur_score = calcScore();
  best_score = -(1e9);
  updateBest();
  start_temp = (double)abs(cur_score) / 5e5;
  end_temp = 0;
  t_manager.update();
}

void output() {
  for (int i = 1; i <= D; i++) {
    assert(cur_schedule[i] >= 0 && cur_schedule[i] <= 25);
    cout << cur_schedule[i] + 1 << endl;
  }
}

void displeyInfo() {
  cerr << endl;
  cerr << "cur_score = " << cur_score << endl;
  cerr << "best_score = " << best_score << endl;
  cerr << "step = " << step << endl;
  cerr << "changed = " << changed_ << endl;
  cerr << "replace = " << replace_ << endl;
  cerr << "shift = " << shift_ << endl;
  cerr << "perm = " << perm_ << endl;
  cerr << "time passed = " << setprecision(3) << fixed
       << t_manager.passed_ratio() << endl;
  cerr << endl;
}

int naiveCalc() {
  int res = 0;
  for (int i = 1; i <= D; i++) {
    for (int j = 0; j < CONTEST; j++) {
      if (j == cur_schedule[i]) {
        res += S[i][j];
      }
      int k = 0;
      for (int l = 1; l <= i; l++)
        if (cur_schedule[l] == j)
          k = l;
      res -= C[j] * (i - k);
    }
    // cout << res << endl;
  }
  return res;
}

int naiveCalcBest() {
  int res = 0;
  for (int i = 1; i <= D; i++) {
    for (int j = 0; j < CONTEST; j++) {
      if (j == best_schedule[i]) {
        res += S[i][j];
      }
      int k = 0;
      for (int l = 1; l <= i; l++)
        if (best_schedule[l] == j)
          k = l;
      res -= C[j] * (i - k);
    }
    // cout << res << endl;
  }
  return res;
}

signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);

  init();
  displeyInfo();

  bool upd;
  for (int i = 0; !t_manager.is_timeover(); i++) {
    if (i % 255 == 0) {
      t_manager.update();
    }

    upd = false;
    if (!upd)
      upd |= shift();
    if (!upd)
      upd |= replace();

    if (t_manager.passed_ratio() > 0.7)
      updateBest();

    // if (i % 1000 == 0) {
    //   int get = naiveCalcBest();
    //   if (get != best_score) {
    //     cerr << "i = " << i << " get = " << get << " best_score = " <<
    //     best_score << endl; int get2 = naiveCalc(); cerr << "get2 = " << get2
    //     << " cur_score = " << cur_score << endl;
    //   }
    //   assert(get == best_score);
    // }

    if (i % 5000 == 0) {
      displeyInfo();
    }
  }

  output();
  displeyInfo();
  return 0;
}