#include #include #include #include #include using namespace std; vector> a, sol; vector> onRow, onCol, onCell; int n; bool solved; bool onColCell[26][26][26]; bool onRowCell[26][26][26]; int cell(int i, int j) { return (i/n) * n + (j/n); } void place(int i, int j, int k) { onRow[i][k] = true; onCol[j][k] = true; onCell[cell(i, j)][k] = true; a[i][j] = k; } void unplace(int i, int j, int k) { onRow[i][k] = false; onCol[j][k] = false; onCell[cell(i, j)][k] = false; a[i][j] = 0; } void read() { cin >> n; for (int i = 0; i <= n*n; ++i) { for (int j = 0; j <= n*n; ++j) { for (int k = 0; k <= n*n; ++k) onRowCell[i][j][k] = onColCell[i][j][k] = true; } } a = vector>(n*n+1, vector(n*n+1)); onRow = onCol = onCell = vector>(n*n+1, vector(n*n+1)); for (int i = 0; i < n*n; ++i) { for (int j = 0; j < n*n; ++j) { int x; cin >> x; if (x != 0) place(i, j, x); } } } void back(int i, int j) { // cout << "HERE" << endl; if (solved) return; if (j == n*n) { // cout << "HERE" << endl; if (i == n*n-1) { sol = a; solved = true; return; } back(i+1, 0); return; } if (a[i][j] != 0) { back(i, j+1); } else { int cl = cell(i, j); for (int k = 1; k <= n*n; ++k) { if (onRow[i][k] || onCol[j][k] || onCell[cell(i, j)][k] || !onColCell[cl][j%n][k] || !onRowCell[cl][i%n][k]) continue; place(i, j, k); back(i, j+1); unplace(i, j, k); } } } void print() { for (int i = 0; i < n*n; ++i) { for (int j = 0; j < n*n; ++j) { cout << sol[i][j] << " "; } cout << "\n"; } } void eliminate(bool has[][26][26], int who, int nr, vector& cells) { set s; for (auto el : cells) { for (int col = 0; col < n; ++col) { if (has[el][col][nr]) s.insert(col); } } bool ok = false; for (int col = 0; col < n; ++col) { if (s.find(col) == s.end()) { ok = true; } } if (!ok) { return; } for (int col = 0; col < n; ++col) { has[who][col][nr] = false; } for (int col = 0; col < n; ++col) { if (s.find(col) == s.end()) { has[who][col][nr] = true; } } } void bulan() { for (int i = 0; i < n*n; ++i) { for (int j = 0; j < n*n; ++j) { if (a[i][j] != 0) { for (int row = 0; row < n; ++row) { onRowCell[cell(i, j)][row][a[i][j]] = false; } onRowCell[cell(i, j)][i][a[i][j]] = true; for (int col = 0; col < n; ++col) { onRowCell[cell(i, j)][col][a[i][j]] = false; } onColCell[cell(i, j)][j][a[i][j]] = true; } } } int cnt = 1000; while (cnt) { for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { for (int nr = 1; nr <= n*n; ++nr) { vector cells; for (int k = 0; k < n; ++k) { if (i != k) cells.push_back(k*n + j); } eliminate(onColCell, i*n+j, nr, cells); cells.clear(); for (int k = 0; k < n; ++k) { if (j != k) cells.push_back(i*n + k); } eliminate(onRowCell, i*n+j, nr, cells); } } } --cnt; } // cout << "HERE" << endl; } void solve() { read(); bulan(); solved = false; back(0, 0); // cout << "HERE" << endl; print(); } int main() { int tests = 1; for (;tests; --tests) { solve(); } }