Language: C++

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <chrono>
using namespace std;

class Timer {
	chrono::high_resolution_clock::time_point start, end;
	double limit;

public:
	Timer() {
		start = chrono::high_resolution_clock::now();
	}
	Timer(double l) {
		start = chrono::high_resolution_clock::now();
		limit = l;
	}

	double getTime() {
		end = chrono::high_resolution_clock::now();
		return chrono::duration<double>(end - start).count();
	}

	bool Over() {
		if (getTime() > limit) {
			return true;
		}
		return false;
	}

	void setLimit(double l) {
		limit = l;
	}
	void setStart() { start = chrono::high_resolution_clock::now(); }
	double getLimit() { return limit; }
};

class XorShift {
	unsigned static int x, y, z, w;
public:
	XorShift() {
		x = 31103110, y = 123456789, z = 521288629, w = 88675123;
	}

	unsigned int nextInt()
	{
		unsigned int t;
		t = (x ^ (x << 11)); x = y; y = z; z = w;
		return(w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)));
	}
};
unsigned int XorShift::x, XorShift::y, XorShift::z, XorShift::w;

int C[26];
int S[365][26];

int ans[365];
int best_ans[365];

int score;
int best_score;

int list[26][365];
int list_n[26];

class Solver
{
	int D;

	Timer tmr;
	XorShift rnd;
public:
	void solve()
	{
		sa();
	}

	int binary_search(int r, int d, bool flag)
	{
		int ret;

		int left, right, mid;
		if (flag)
		{
			left = 0, right = list_n[r];
			while (left < right)
			{
				mid = (left + right) / 2;
				if (list[r][mid] < d)left = mid+1;
				else right = mid;
			}
			ret = list[r][right-1];
		}
		else
		{
			ret = 0;
			left = 0, right = list_n[r];
			while (left < right)
			{
				mid = (left + right) / 2;
				if (list[r][mid] > d)right = mid;
				else left = mid + 1;
			}
			ret = list[r][left];
		}

		return ret;
	}

	void sa()
	{
		double current = tmr.getTime();

		double startTemp = 2000;
		double endTemp = 100;
		double diffTemp = (endTemp - startTemp) / tmr.getLimit();

		int loop = 0;
		while (1)
		{
			loop++;
			if (loop % 10000 == 0)
			{
				current = tmr.getTime();
				if (current > tmr.getLimit())
					break;
			}

			int d = rnd.nextInt() % D;
			int r = rnd.nextInt() % 26;

			if (ans[d] == r)continue;

			int prev_last = binary_search(ans[d], d + 1, true);

			int prev_last2 = binary_search(ans[d], d + 1, false);

			int next_last = binary_search(r, d + 1, true);

			int next_last2 = binary_search(r, d + 1, false);

			int delta = S[d][r] - S[d][ans[d]];

			int next_n = next_last2 - next_last;
			delta -= C[r] * ((d - next_last) * (d - next_last + 1) / 2 + (next_last2 - d - 2) * (next_last2 - d - 1) / 2 - next_n * (next_n - 1) / 2);
			int prev_n = prev_last2 - prev_last;
			delta -= C[ans[d]] * (prev_n * (prev_n - 1) / 2 - (d - prev_last) * (d + 1 - prev_last) / 2 - (prev_last2 - d - 2) * (prev_last2 - d - 1) / 2);

			bool accept = false;

			if (delta >= 0)
			{
				accept = true;
			}
			else
			{
				double temp = startTemp + diffTemp * current;
				double prob = exp(delta / temp);

				accept = prob * UINT32_MAX > rnd.nextInt();
			}

			if (accept)
			{
				int prev_r = ans[d];

				score += delta;
				ans[d] = r;

				list_n[r]++;
				for (int i = list_n[r] - 1; i > 0; i--)
				{
					if(list[r][i-1] > d+1)
						swap(list[r][i], list[r][i-1]);
					else
					{
						list[r][i] = d+1;
						break;
					}
				}

				list_n[prev_r]--;
				for (int i = 0; i < list_n[prev_r]; i++)
				{
					if (list[prev_r][i] >= d + 1)
					{
						swap(list[prev_r][i], list[prev_r][i+1]);
					}
				}

				if (score > best_score)
				{
					best_score = score;
					memcpy(best_ans, ans, sizeof(ans));

					//cerr<<score<<endl;
				}
			}
		}
		//cerr << loop << endl;
		//memcpy(ans, best_ans, sizeof(best_ans));
		//cerr << best_score << " " << scoring() << endl;
	}

	void init()
	{
		input();

		tmr.setLimit(1.8);
		tmr.setStart();

		for (int i = 0; i < 26; i++)
		{
			list[i][list_n[i]++] = 0;
		}

		for (int i = 0; i < D; i++)
		{
			ans[i] = rnd.nextInt() % 26;
			list[ans[i]][list_n[ans[i]]++] = i + 1;
		}
		for (int i = 0; i < 26; i++)
		{
			list[i][list_n[i]++] = D + 1;
		}

		memcpy(best_ans, ans, sizeof(ans));

		best_score = score = scoring();
	}

	int scoring()
	{
		int ret = 0;

		vector<int>last(26);
		for (int i = 0; i < D; i++)
		{
			ret += S[i][ans[i]];
			last[ans[i]] = i + 1;
			for (int j = 0; j < 26; j++)
				ret -= C[j] * (i + 1 - last[j]);
		}

		return ret;
	}

	void input()
	{
		cin >> D;
		for (int i = 0; i < 26; i++)
			cin >> C[i];

		for (int i = 0; i < D; i++)for (int j = 0; j < 26; j++)
			cin >> S[i][j];
	}

	void output()
	{
		for (int i = 0; i < D; i++)
			cout << best_ans[i] + 1 << endl;
	}

	void run()
	{
		init();

		solve();

		output();
	}

};

int main() {
	Solver slv;
	slv.run();

	return 0;
}

Compiler output:
a.cc: In member function 'void Solver::sa()':
a.cc:160:47: error: 'exp' was not declared in this scope
  160 |                                 double prob = exp(delta / temp);
      |                                               ^~~
a.cc:196:41: error: 'memcpy' was not declared in this scope
  196 |                                         memcpy(best_ans, ans, sizeof(ans));
      |                                         ^~~~~~
a.cc:6:1: note: 'memcpy' is defined in header '<cstring>'; this is probably fixable by adding '#include <cstring>'
    5 | #include <chrono>
  +++ |+#include <cstring>
    6 | using namespace std;
a.cc: In member function 'void Solver::init()':
a.cc:229:17: error: 'memcpy' was not declared in this scope
  229 |                 memcpy(best_ans, ans, sizeof(ans));
      |                 ^~~~~~
a.cc:229:17: note: 'memcpy' is defined in header '<cstring>'; this is probably fixable by adding '#include <cstring>'