// Task 1 2015/2016 competition CodeIT // Plamen Tomov Sofia #define _CRT_SECURE_NO_WARNINGS #include #include #include #include using namespace std; int N, R, K, temK, M, q, set_timer; int table[201][201]; int tem_size[51]; int field[201][201]; int end_ray_i[8], end_ray_j[8]; int di[] = { -1, -1, 0, 1, 1, 1, 0, -1 }; int dj[] = { 0, 1, 1, 1, 0, -1, -1, -1 }; struct max_points { int i, j, sum, set; bool operator < (const max_points &a) const { return (this->sum > a.sum); } }max_p[40500]; struct result { int i, j; }res[40500]; //#include"tes.h" void Input() { FILE *in = fopen("queens.in", "r"); fscanf(in, "%i %i %i", &N, &R, &K); for (int i = 1; i <= N; i++){ for (int j = 1; j <= N; j++) { fscanf(in, "%i", &field[i][j]); } } M = N*N; } void SetEndRay() { end_ray_i[2] = end_ray_i[6] = end_ray_j[0] = end_ray_j[4] = 300; end_ray_i[3] = end_ray_i[4] = end_ray_i[5] = end_ray_j[1] = end_ray_j[2] = end_ray_j[3] = N; } int CalPoint(int i, int j) { int p = 1; while (p < 51) { tem_size[p] = 0; p++; } int sum = field[i][j] * 4; tem_size[field[i][j]] = 4; for (int k = 0; k < 8; k++) { int ti = i, tj = j; for (int s = 1; s <= R; s++) { if (ti == end_ray_i[k] || tj == end_ray_j[k]) break; ti += di[k]; tj += dj[k]; sum += field[ti][tj]; tem_size[field[ti][tj]]++; } } int k = 1; p = 1; while (p < 51) { if (tem_size[p] > k) k = tem_size[p]; p++; } sum = sum * k; return sum ; } int ScanTable(int i, int j) { int new_doubles = 0; for (int k = 0; k < 8; k++) { int ti = i, tj = j; for (int s = 1; s <= R; s++) { if (ti == end_ray_i[k] || tj == end_ray_j[k]) break; ti += di[k]; tj += dj[k]; if (table[ti][tj] > 0) new_doubles++; if (new_doubles > K) return 2000; } } return new_doubles; } void Output() { FILE *out = fopen("queens.out", "w"); for (int k = 1; k <= q; k++) { fprintf(out, "%i %i\n", res[k].i, res[k].j); } } void Solve() { int p = 0, sq, min_sq, tk, x; SetEndRay(); for (int i = 1; i <= N; i++) { for (int j = 1; j <= N; j++) { p++; max_p[p].sum = CalPoint(i, j); max_p[p].i = i; max_p[p].j = j; } } sort(&max_p[1], &max_p[M+1]); //====== x = 1; res[x].i = max_p[x].i; res[x].j = max_p[x].j; q++; table[max_p[x].i][max_p[x].j]++; max_p[x].set++; //===== for (int a = 1; a <= M; a++){ if (GetTickCount() - set_timer > 4900) break; min_sq = 20000, p = 0; for (int k = 1; k <= M; k++) { if (max_p[k].set > 0) continue; sq = ScanTable(max_p[k].i, max_p[k].j); if (sq < min_sq) { min_sq = sq; tk = k; } p++; if (p < 80 && k < M) continue; if (temK + min_sq > K) continue; q++; res[q].i = max_p[tk].i; res[q].j = max_p[tk].j; table[max_p[tk].i][max_p[tk].j]++; temK += min_sq; max_p[tk].set++; break; } } } int main() { set_timer = GetTickCount(); Input(); Solve(); Output(); return 0; }