#include #include #include #include #include #include #include #include #include #define read(a) scanf("%d", &a) #define print(a, b) printf("%d %d\n", a, b) #define FOR(a, b) for(int a = 0; a < b; a++) static const int MAX_SIZE = 205; static const int MAX = MAX_SIZE*MAX_SIZE; time_t curTime; time_t maxTime = 4900; time_t maxFstTime = 2000; struct Cell { int val; int row, col; Cell() {} Cell(int a, int b, int c) : Cell() { this->row = a; this->col = b; this->val = c; } }; Cell make_cell(int a, int b) { Cell c(a, b, 0); return c; } bool cmp(Cell a, Cell b) { return a.val > b.val; } using namespace std; bool hasOutput = false; int n, k, r, bestScore, score, emptyCells, bestStateSize; int nums[55]; int mat[MAX_SIZE][MAX_SIZE]; int val[MAX_SIZE][MAX_SIZE]; int coll[MAX_SIZE][MAX_SIZE]; Cell sol[MAX]; Cell all[MAX]; Cell bestState[MAX]; void input() { read(n); read(r); read(k); FOR(i, n) FOR(j, n) read(mat[i][j]); } void precalk() { int cnt = 0; FOR(i, n) { FOR(j, n) { fill(nums, nums + 55, 0); int maxNum = 0; for(int q = 0 - r; q < r + 1; q++) { if (i + q >= 0 and i + q = 0 and j + q < n) { val[i][j] += mat[i][j+q];nums[mat[i][j+q]]++; if (maxNum < nums[mat[i][j+q]]) maxNum = nums[mat[i][j+q]]; } if (i + q >= 0 and i + q < n and j + q >= 0 and j + q < n) { val[i][j] += mat[i+q][j+q];nums[mat[i+q][j+q]]++; if (maxNum < nums[mat[i+q][j+q]]) maxNum = nums[mat[i+q][j+q]]; } if (i + q >= 0 and i + q < n and j - q >= 0 and j - q < n) { val[i][j] += mat[i+q][j-q]; nums[mat[i+q][j-q]]++; if (maxNum < nums[mat[i+q][j-q]]) maxNum = nums[mat[i+q][j-q]]; } } val[i][j] *= maxNum; Cell temp(i, j, val[i][j]); all[cnt] = temp; cnt++; } } } bool noTime() { return clock() - curTime >= maxTime; } void output() { FOR(i, bestStateSize) print(bestState[i].row + 1, bestState[i].col + 1); } bool used[MAX_SIZE][MAX_SIZE], visited[MAX_SIZE][MAX_SIZE]; void putCollisions(Cell a) { int cnt = 0; int i = a.row - r; int j = a.col - r; int k = a.row - r; int q = a.col + r; while(i < n or j < n or q >= 0 or k >= 0) { if(cnt > r + r) break; if(i >= 0 and i < n) { if(coll[i][a.col] == 0) emptyCells++; coll[i][a.col]++; } if(j >= 0 and j < n) { if(coll[a.row][j] == 0) emptyCells++; coll[a.row][j]++; } if(i < n and j < n and i >= 0 and j >= 0) { if(coll[i][j] == 0) emptyCells++; coll[i][j]++; } if(q >= 0 and k >= 0 and q < n and k < n) { if(coll[k][q] == 0) emptyCells++; coll[k][q]++; } i++; j++; q--; k++; cnt++; } } void setZero() { FOR(i, n) FOR(j, n) coll[i][j] = 0, used[i][j] = false; } int curSize = 0; void solve_sorted() { FOR(i, n*n) { curSize = 0; emptyCells = 0; setZero(); sol[0] = all[i]; curSize++; putCollisions(all[i]); score = all[i].val; used[all[i].row][all[i].col] = true; for(int j = 0; emptyCells < n*n; j++) { if(coll[all[j].row][all[j].col] == 0) { used[all[j].row][all[j].col] = true; sol[curSize] = all[j]; curSize++; score += all[j].val; putCollisions(all[j]); } } int collisions = 0; while(collisions < k) { int bestCurScore = 0; Cell bestCell(0, 0, 0); FOR(r, n) FOR(c, n) { if(collisions + coll[r][c] <= k and used[r][c] == false) { int vall = 0; if(coll[r][c] == 0) vall = val[r][c]; else vall = val[r][c]/coll[r][c]; if(vall > bestCurScore) { bestCurScore = vall; bestCell = make_cell(r, c); bestCell.val = val[r][c]; } } } if(bestCell.val == 0) break; score += bestCell.val; collisions += coll[bestCell.row][bestCell.col]; sol[curSize] = bestCell; curSize++; putCollisions(bestCell); used[bestCell.row][bestCell.col] = true; if(noTime()) { if(score > bestScore) { bestScore = score; FOR(q, curSize) bestState[q] = sol[q]; bestStateSize = curSize; } return; } } if(score > bestScore) { bestScore = score; FOR(q, curSize) bestState[q] = sol[q]; bestStateSize = curSize; } if(noTime())return; } } void solve_unsorted() { FOR(i, n*n) { curSize = 0; emptyCells = 0; setZero(); sol[0] = all[i]; curSize++; putCollisions(all[i]); score = all[i].val; used[all[i].row][all[i].col] = true; for(int j = 0; emptyCells < n*n; j++) { if(coll[all[j].row][all[j].col] == 0) { used[all[j].row][all[j].col] = true; sol[curSize] = all[j]; curSize++; score += all[j].val; putCollisions(all[j]); } } int collisions = 0; while(collisions <= k) { int bestCurScore = 0; Cell bestCell(0, 0, 0); FOR(r, n) FOR(c, n) { if(collisions + coll[r][c] <= k and used[r][c] == false) { int vall = 0; if(coll[r][c] == 0) vall = val[r][c]; else vall = val[r][c]/coll[r][c]; if(vall > bestCurScore) { bestCurScore = vall; bestCell = make_cell(r, c); bestCell.val = val[r][c]; } } } if(bestCell.val == 0) break; score += bestCell.val; collisions += coll[bestCell.row][bestCell.col]; sol[curSize] = bestCell; curSize++; putCollisions(bestCell); used[bestCell.row][bestCell.col] = true; if(curTime < maxFstTime) { if(score > bestScore) { bestScore = score; FOR(q, curSize) bestState[q] = sol[q]; bestStateSize = curSize; } return; } } if(score > bestScore) { bestScore = score; FOR(q, curSize) bestState[q] = sol[q]; bestStateSize = curSize; } if(curTime < maxFstTime)return; } } int main() { freopen("queens.in", "r", stdin); freopen("queens.out", "w", stdout); curTime = clock(); input(); precalk(); solve_unsorted(); sort(all, all + n*n, cmp); solve_sorted(); if(bestScore < score) { FOR(q, curSize) bestState[q] = sol[q]; bestStateSize = curSize; } output(); return 0; }