//Code by Patcas Csaba #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; #define LL long long #define PII pair #define VB vector #define VI vector #define VD vector #define VS vector #define VPII vector > #define VVI vector < VI > #define VVB vector < VB > #define FORN(i, n) for(int i = 0; i < (n); ++i) #define FOR(i, a, b) for(int i = (a); i <= (b); ++i) #define FORD(i, a, b) for(int i = (a); i >= (b); --i) #define FORI(it, X) for(__typeof((X).begin()) it = (X).begin(); it !=(X).end(); ++it) #define REPEAT do{ #define UNTIL(x) }while(!(x)); #define SZ size() #define BG begin() #define EN end() #define CL clear() #define X first #define Y second #define RS resize #define PB push_back #define MP make_pair #define ALL(x) x.begin(), x.end() #define IN_FILE "a.in" #define OUT_FILE "a.out" int n, m; VVI a; vector> lines, cols; vector > > rects; vector > > pos; set inter(set aa, set bb) { set ans; for(set::iterator it = aa.BG; it!=aa.EN; ++it) if (bb.count(*it)) ans.insert(*it); return ans; } void updatePos() { FOR(i, 1, n * n) FOR(j, 1, n * n) { pos[i][j] = lines[i]; pos[i][j] = inter(pos[i][j], cols[j]); pos[i][j] = inter(pos[i][j], rects[(i - 1) / n + 1][(j - 1) / n + 1]); } } void buildPos() { FOR(i, 1, n * n) FOR(j, 1, n * n) if (a[i][j]) { lines[i].erase(a[i][j]); cols[j].erase(a[i][j]); rects[(i - 1) / n + 1][(j - 1) / n + 1].erase(a[i][j]); } } void back(int sp) { cerr << sp << " "; if (sp == m) { FOR(i, 1, n * n) { FOR(j, 1, n * n) cout << a[i][j]; cout << endl; } exit(0); } int mini = n * n, bestI, bestJ; FOR(i, 1, n * n) FOR(j, 1, n * n) if (pos[i][j].SZ == 1) { int val = *pos[i][j].BG; a[i][j] = val; lines[i].erase(val); cols[j].erase(val); rects[(i - 1) / n + 1][(j - 1) / n + 1].erase(val); updatePos(); back(sp + 1); } else { if (pos[i][j].SZ < mini) { mini = pos[i][j].SZ; bestI = i; bestJ = j; } } for(set :: iterator it = pos[bestI][bestJ].BG; it != pos[bestI][bestJ].EN; ++it) { int val = *it; a[bestI][bestJ] = val; lines[bestI].erase(val); cols[bestJ].erase(val); rects[(bestI - 1) / n + 1][(bestJ - 1) / n + 1].erase(val); updatePos(); back(sp + 1); } } int main() { //Read data //freopen(IN_FILE, "r", stdin); //freopen(OUT_FILE, "w", stdout); //Solve cin >> n; a.RS(n * n + 1, VI(n * n + 1)); m = n * n * n * n; FOR(i, 1, n * n) { FOR(j, 1, n * n) { cin >> a[i][j]; if (a[i][j]) --m; } } lines.RS(n * n + 1); cols.RS(n * n + 1); rects.RS(n + 1, vector > (n + 1)); FOR(i, 1, n * n) FOR(j, 1, n * n) { lines[i].insert(j); cols[i].insert(j); } FOR(i, 1, n) FOR(j, 1, n) FOR(k, 1, n * n) rects[i][j].insert(k); buildPos(); pos.RS(n * n + 1, vector > (n * n + 1)); updatePos(); //Write data back(1); return 0; }