// knight_heuristic.cpp
// Warnsdorff heuristic + safe randomization to maximize Score = sum a[r][c]*(r+1 + c+1)
// Input: n
// Output: n lines each with n integers (visit order 1..n^2)
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
struct Cand { int r, c, deg, weight; };
const int dr[8] = {2,1,-1,-2,-2,-1,1,2};
const int dc[8] = {1,2,2,1,-1,-2,-2,-1};
int n;
std::mt19937_64 rng((unsigned)chrono::high_resolution_clock::now().time_since_epoch().count());
inline bool inb(int r, int c){
return r>=0 && r<n && c>=0 && c<n;
}
// Try one Warnsdorff run starting at (sr,sc).
// top_shuffle: shuffle among top this many candidates after sorting by (deg, weight).
// returns matrix a (n x n) with visit indices (1..n^2), empty vector if failed
vector<int> attempt_warnsdorff(int sr, int sc, int top_shuffle){
vector<int> a(n*n, 0); // a[r*n + c] = visit index
int r = sr, c = sc;
a[r*n + c] = 1;
for(int step=2; step<=n*n; ++step){
vector<Cand> cand;
cand.reserve(8);
for(int k=0;k<8;++k){
int nr = r + dr[k], nc = c + dc[k];
if(!inb(nr,nc)) continue;
if(a[nr*n + nc] != 0) continue;
int deg = 0;
for(int k2=0;k2<8;++k2){
int nnr = nr + dr[k2], nnc = nc + dc[k2];
if(inb(nnr,nnc) && a[nnr*n + nnc] == 0) ++deg;
}
cand.push_back({nr, nc, deg, nr + nc}); // weight = r+c (0-indexed)
}
if(cand.empty()){
return {}; // failed
}
sort(cand.begin(), cand.end(), [](const Cand &A, const Cand &B){
if(A.deg != B.deg) return A.deg < B.deg;
return A.weight < B.weight;
});
int top = min<int>(top_shuffle, (int)cand.size());
if(top > 1){
// shuffle only the prefix top to break ties / diversify, safe wrt strict weak ordering
shuffle(cand.begin(), cand.begin() + top, rng);
}
// choose first candidate after possible shuffle
r = cand[0].r;
c = cand[0].c;
a[r*n + c] = step;
}
return a;
}
inline long long calc_score(const vector<int>& a){
// a size == n*n, a[pos] = visit index (1..n^2)
long long sc = 0;
for(int r=0;r<n;++r){
for(int c=0;c<n;++c){
int val = a[r*n + c];
// Score uses 1-based r,c in statement: (r+c)
sc += 1LL * val * ( (r+1) + (c+1) );
}
}
return sc;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
if(!(cin >> n)) return 0;
if(n <= 0) return 0;
// quick small-n handling: for n <= 4 knights tour mostly doesn't exist except trivial n=1
if(n == 1){
cout << 1 << '\n';
return 0;
}
// parameters — bạn có thể điều chỉnh:
const int MAX_TRIES = 1500; // tổng số lần thử (tăng nếu có thời gian)
const int TOP_SHUFFLE = 6; // shuffle top-K candidates after sorting
const int START_PRESET = 8; // số lần thử các start preset trước khi random starts
// candidate starts: corners, near-corners, center-ish
vector<pair<int,int>> starts;
starts.push_back({0,0});
starts.push_back({0,n-1});
starts.push_back({n-1,0});
starts.push_back({n-1,n-1});
if(n > 6){
starts.push_back({1,1});
starts.push_back({1,n-2});
starts.push_back({n-2,1});
starts.push_back({n-2,n-2});
}
// also add some center starts
starts.push_back({n/2, n/2});
starts.push_back({n/2, (n-1)/2});
vector<int> best;
ll bestScore = -1;
// deterministic first: try each preset start once without shuffle to get decent baseline
for(auto &p : starts){
auto res = attempt_warnsdorff(p.first, p.second, 1); // no shuffle
if(!res.empty()){
ll sc = calc_score(res);
if(sc > bestScore){
bestScore = sc;
best = res;
}
}
}
// randomized attempts
for(int t=0; t<MAX_TRIES; ++t){
int sr, sc;
if(t < (int)starts.size() * 2){
// try each start a couple times
auto &p = starts[t % starts.size()];
sr = p.first; sc = p.second;
} else {
// random start
sr = rng() % n;
sc = rng() % n;
}
auto res = attempt_warnsdorff(sr, sc, TOP_SHUFFLE);
if(res.empty()) continue;
ll scv = calc_score(res);
if(scv > bestScore){
bestScore = scv;
best = res;
}
// small optimization: if found a full tour whose last visited cell is one of max (r+c) maybe it's already very good,
// but we continue to search to try to get even higher score.
}
// If still empty: fallback one more exhaustive small attempt from (0,0) without shuffle
if(best.empty()){
auto res = attempt_warnsdorff(0,0,1);
if(!res.empty()){
best = res;
bestScore = calc_score(res);
}
}
// If still empty (rare), produce trivial sequential fill to satisfy format (but checker gives 0)
if(best.empty()){
for(int r=0;r<n;++r){
for(int c=0;c<n;++c){
cout << (r*n + c + 1) << (c+1==n?'\n':' ');
}
}
return 0;
}
// Print best tour (row-major)
for(int r=0;r<n;++r){
for(int c=0;c<n;++c){
cout << best[r*n + c] << (c+1==n?'\n':' ');
}
}
// If you want to see the score for debugging, uncomment:
// cerr << "BestScore=" << bestScore << "\n";
return 0;
}
Ly8ga25pZ2h0X2hldXJpc3RpYy5jcHAKLy8gV2FybnNkb3JmZiBoZXVyaXN0aWMgKyBzYWZlIHJhbmRvbWl6YXRpb24gdG8gbWF4aW1pemUgU2NvcmUgPSBzdW0gYVtyXVtjXSoocisxICsgYysxKQovLyBJbnB1dDogbgovLyBPdXRwdXQ6IG4gbGluZXMgZWFjaCB3aXRoIG4gaW50ZWdlcnMgKHZpc2l0IG9yZGVyIDEuLm5eMikKCiNpbmNsdWRlIDxiaXRzL3N0ZGMrKy5oPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwp1c2luZyBsbCA9IGxvbmcgbG9uZzsKc3RydWN0IENhbmQgeyBpbnQgciwgYywgZGVnLCB3ZWlnaHQ7IH07Cgpjb25zdCBpbnQgZHJbOF0gPSB7MiwxLC0xLC0yLC0yLC0xLDEsMn07CmNvbnN0IGludCBkY1s4XSA9IHsxLDIsMiwxLC0xLC0yLC0yLC0xfTsKCmludCBuOwpzdGQ6Om10MTk5MzdfNjQgcm5nKCh1bnNpZ25lZCljaHJvbm86OmhpZ2hfcmVzb2x1dGlvbl9jbG9jazo6bm93KCkudGltZV9zaW5jZV9lcG9jaCgpLmNvdW50KCkpOwoKaW5saW5lIGJvb2wgaW5iKGludCByLCBpbnQgYyl7CiAgICByZXR1cm4gcj49MCAmJiByPG4gJiYgYz49MCAmJiBjPG47Cn0KCi8vIFRyeSBvbmUgV2FybnNkb3JmZiBydW4gc3RhcnRpbmcgYXQgKHNyLHNjKS4KLy8gdG9wX3NodWZmbGU6IHNodWZmbGUgYW1vbmcgdG9wIHRoaXMgbWFueSBjYW5kaWRhdGVzIGFmdGVyIHNvcnRpbmcgYnkgKGRlZywgd2VpZ2h0KS4KLy8gcmV0dXJucyBtYXRyaXggYSAobiB4IG4pIHdpdGggdmlzaXQgaW5kaWNlcyAoMS4ubl4yKSwgZW1wdHkgdmVjdG9yIGlmIGZhaWxlZAp2ZWN0b3I8aW50PiBhdHRlbXB0X3dhcm5zZG9yZmYoaW50IHNyLCBpbnQgc2MsIGludCB0b3Bfc2h1ZmZsZSl7CiAgICB2ZWN0b3I8aW50PiBhKG4qbiwgMCk7IC8vIGFbcipuICsgY10gPSB2aXNpdCBpbmRleAogICAgaW50IHIgPSBzciwgYyA9IHNjOwogICAgYVtyKm4gKyBjXSA9IDE7CiAgICBmb3IoaW50IHN0ZXA9Mjsgc3RlcDw9bipuOyArK3N0ZXApewogICAgICAgIHZlY3RvcjxDYW5kPiBjYW5kOwogICAgICAgIGNhbmQucmVzZXJ2ZSg4KTsKICAgICAgICBmb3IoaW50IGs9MDtrPDg7KytrKXsKICAgICAgICAgICAgaW50IG5yID0gciArIGRyW2tdLCBuYyA9IGMgKyBkY1trXTsKICAgICAgICAgICAgaWYoIWluYihucixuYykpIGNvbnRpbnVlOwogICAgICAgICAgICBpZihhW25yKm4gKyBuY10gIT0gMCkgY29udGludWU7CiAgICAgICAgICAgIGludCBkZWcgPSAwOwogICAgICAgICAgICBmb3IoaW50IGsyPTA7azI8ODsrK2syKXsKICAgICAgICAgICAgICAgIGludCBubnIgPSBuciArIGRyW2syXSwgbm5jID0gbmMgKyBkY1trMl07CiAgICAgICAgICAgICAgICBpZihpbmIobm5yLG5uYykgJiYgYVtubnIqbiArIG5uY10gPT0gMCkgKytkZWc7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2FuZC5wdXNoX2JhY2soe25yLCBuYywgZGVnLCBuciArIG5jfSk7IC8vIHdlaWdodCA9IHIrYyAoMC1pbmRleGVkKQogICAgICAgIH0KICAgICAgICBpZihjYW5kLmVtcHR5KCkpewogICAgICAgICAgICByZXR1cm4ge307IC8vIGZhaWxlZAogICAgICAgIH0KICAgICAgICBzb3J0KGNhbmQuYmVnaW4oKSwgY2FuZC5lbmQoKSwgW10oY29uc3QgQ2FuZCAmQSwgY29uc3QgQ2FuZCAmQil7CiAgICAgICAgICAgIGlmKEEuZGVnICE9IEIuZGVnKSByZXR1cm4gQS5kZWcgPCBCLmRlZzsKICAgICAgICAgICAgcmV0dXJuIEEud2VpZ2h0IDwgQi53ZWlnaHQ7CiAgICAgICAgfSk7CiAgICAgICAgaW50IHRvcCA9IG1pbjxpbnQ+KHRvcF9zaHVmZmxlLCAoaW50KWNhbmQuc2l6ZSgpKTsKICAgICAgICBpZih0b3AgPiAxKXsKICAgICAgICAgICAgLy8gc2h1ZmZsZSBvbmx5IHRoZSBwcmVmaXggdG9wIHRvIGJyZWFrIHRpZXMgLyBkaXZlcnNpZnksIHNhZmUgd3J0IHN0cmljdCB3ZWFrIG9yZGVyaW5nCiAgICAgICAgICAgIHNodWZmbGUoY2FuZC5iZWdpbigpLCBjYW5kLmJlZ2luKCkgKyB0b3AsIHJuZyk7CiAgICAgICAgfQogICAgICAgIC8vIGNob29zZSBmaXJzdCBjYW5kaWRhdGUgYWZ0ZXIgcG9zc2libGUgc2h1ZmZsZQogICAgICAgIHIgPSBjYW5kWzBdLnI7CiAgICAgICAgYyA9IGNhbmRbMF0uYzsKICAgICAgICBhW3IqbiArIGNdID0gc3RlcDsKICAgIH0KICAgIHJldHVybiBhOwp9CgppbmxpbmUgbG9uZyBsb25nIGNhbGNfc2NvcmUoY29uc3QgdmVjdG9yPGludD4mIGEpewogICAgLy8gYSBzaXplID09IG4qbiwgYVtwb3NdID0gdmlzaXQgaW5kZXggKDEuLm5eMikKICAgIGxvbmcgbG9uZyBzYyA9IDA7CiAgICBmb3IoaW50IHI9MDtyPG47KytyKXsKICAgICAgICBmb3IoaW50IGM9MDtjPG47KytjKXsKICAgICAgICAgICAgaW50IHZhbCA9IGFbcipuICsgY107CiAgICAgICAgICAgIC8vIFNjb3JlIHVzZXMgMS1iYXNlZCByLGMgaW4gc3RhdGVtZW50OiAocitjKQogICAgICAgICAgICBzYyArPSAxTEwgKiB2YWwgKiAoIChyKzEpICsgKGMrMSkgKTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gc2M7Cn0KCmludCBtYWluKCl7CiAgICBpb3M6OnN5bmNfd2l0aF9zdGRpbyhmYWxzZSk7CiAgICBjaW4udGllKG51bGxwdHIpOwogICAgaWYoIShjaW4gPj4gbikpIHJldHVybiAwOwogICAgaWYobiA8PSAwKSByZXR1cm4gMDsKCiAgICAvLyBxdWljayBzbWFsbC1uIGhhbmRsaW5nOiBmb3IgbiA8PSA0IGtuaWdodHMgdG91ciBtb3N0bHkgZG9lc24ndCBleGlzdCBleGNlcHQgdHJpdmlhbCBuPTEKICAgIGlmKG4gPT0gMSl7CiAgICAgICAgY291dCA8PCAxIDw8ICdcbic7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgLy8gcGFyYW1ldGVycyDigJQgYuG6oW4gY8OzIHRo4buDIMSRaeG7gXUgY2jhu4luaDoKICAgIGNvbnN0IGludCBNQVhfVFJJRVMgPSAxNTAwOyAgICAgLy8gdOG7lW5nIHPhu5EgbOG6p24gdGjhu60gKHTEg25nIG7hur91IGPDsyB0aOG7nWkgZ2lhbikKICAgIGNvbnN0IGludCBUT1BfU0hVRkZMRSA9IDY7ICAgICAvLyBzaHVmZmxlIHRvcC1LIGNhbmRpZGF0ZXMgYWZ0ZXIgc29ydGluZwogICAgY29uc3QgaW50IFNUQVJUX1BSRVNFVCA9IDg7ICAgIC8vIHPhu5EgbOG6p24gdGjhu60gY8OhYyBzdGFydCBwcmVzZXQgdHLGsOG7m2Mga2hpIHJhbmRvbSBzdGFydHMKCiAgICAvLyBjYW5kaWRhdGUgc3RhcnRzOiBjb3JuZXJzLCBuZWFyLWNvcm5lcnMsIGNlbnRlci1pc2gKICAgIHZlY3RvcjxwYWlyPGludCxpbnQ+PiBzdGFydHM7CiAgICBzdGFydHMucHVzaF9iYWNrKHswLDB9KTsKICAgIHN0YXJ0cy5wdXNoX2JhY2soezAsbi0xfSk7CiAgICBzdGFydHMucHVzaF9iYWNrKHtuLTEsMH0pOwogICAgc3RhcnRzLnB1c2hfYmFjayh7bi0xLG4tMX0pOwogICAgaWYobiA+IDYpewogICAgICAgIHN0YXJ0cy5wdXNoX2JhY2soezEsMX0pOwogICAgICAgIHN0YXJ0cy5wdXNoX2JhY2soezEsbi0yfSk7CiAgICAgICAgc3RhcnRzLnB1c2hfYmFjayh7bi0yLDF9KTsKICAgICAgICBzdGFydHMucHVzaF9iYWNrKHtuLTIsbi0yfSk7CiAgICB9CiAgICAvLyBhbHNvIGFkZCBzb21lIGNlbnRlciBzdGFydHMKICAgIHN0YXJ0cy5wdXNoX2JhY2soe24vMiwgbi8yfSk7CiAgICBzdGFydHMucHVzaF9iYWNrKHtuLzIsIChuLTEpLzJ9KTsKCiAgICB2ZWN0b3I8aW50PiBiZXN0OwogICAgbGwgYmVzdFNjb3JlID0gLTE7CgogICAgLy8gZGV0ZXJtaW5pc3RpYyBmaXJzdDogdHJ5IGVhY2ggcHJlc2V0IHN0YXJ0IG9uY2Ugd2l0aG91dCBzaHVmZmxlIHRvIGdldCBkZWNlbnQgYmFzZWxpbmUKICAgIGZvcihhdXRvICZwIDogc3RhcnRzKXsKICAgICAgICBhdXRvIHJlcyA9IGF0dGVtcHRfd2FybnNkb3JmZihwLmZpcnN0LCBwLnNlY29uZCwgMSk7IC8vIG5vIHNodWZmbGUKICAgICAgICBpZighcmVzLmVtcHR5KCkpewogICAgICAgICAgICBsbCBzYyA9IGNhbGNfc2NvcmUocmVzKTsKICAgICAgICAgICAgaWYoc2MgPiBiZXN0U2NvcmUpewogICAgICAgICAgICAgICAgYmVzdFNjb3JlID0gc2M7CiAgICAgICAgICAgICAgICBiZXN0ID0gcmVzOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8vIHJhbmRvbWl6ZWQgYXR0ZW1wdHMKICAgIGZvcihpbnQgdD0wOyB0PE1BWF9UUklFUzsgKyt0KXsKICAgICAgICBpbnQgc3IsIHNjOwogICAgICAgIGlmKHQgPCAoaW50KXN0YXJ0cy5zaXplKCkgKiAyKXsKICAgICAgICAgICAgLy8gdHJ5IGVhY2ggc3RhcnQgYSBjb3VwbGUgdGltZXMKICAgICAgICAgICAgYXV0byAmcCA9IHN0YXJ0c1t0ICUgc3RhcnRzLnNpemUoKV07CiAgICAgICAgICAgIHNyID0gcC5maXJzdDsgc2MgPSBwLnNlY29uZDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyByYW5kb20gc3RhcnQKICAgICAgICAgICAgc3IgPSBybmcoKSAlIG47CiAgICAgICAgICAgIHNjID0gcm5nKCkgJSBuOwogICAgICAgIH0KICAgICAgICBhdXRvIHJlcyA9IGF0dGVtcHRfd2FybnNkb3JmZihzciwgc2MsIFRPUF9TSFVGRkxFKTsKICAgICAgICBpZihyZXMuZW1wdHkoKSkgY29udGludWU7CiAgICAgICAgbGwgc2N2ID0gY2FsY19zY29yZShyZXMpOwogICAgICAgIGlmKHNjdiA+IGJlc3RTY29yZSl7CiAgICAgICAgICAgIGJlc3RTY29yZSA9IHNjdjsKICAgICAgICAgICAgYmVzdCA9IHJlczsKICAgICAgICB9CiAgICAgICAgLy8gc21hbGwgb3B0aW1pemF0aW9uOiBpZiBmb3VuZCBhIGZ1bGwgdG91ciB3aG9zZSBsYXN0IHZpc2l0ZWQgY2VsbCBpcyBvbmUgb2YgbWF4IChyK2MpIG1heWJlIGl0J3MgYWxyZWFkeSB2ZXJ5IGdvb2QsCiAgICAgICAgLy8gYnV0IHdlIGNvbnRpbnVlIHRvIHNlYXJjaCB0byB0cnkgdG8gZ2V0IGV2ZW4gaGlnaGVyIHNjb3JlLgogICAgfQoKICAgIC8vIElmIHN0aWxsIGVtcHR5OiBmYWxsYmFjayBvbmUgbW9yZSBleGhhdXN0aXZlIHNtYWxsIGF0dGVtcHQgZnJvbSAoMCwwKSB3aXRob3V0IHNodWZmbGUKICAgIGlmKGJlc3QuZW1wdHkoKSl7CiAgICAgICAgYXV0byByZXMgPSBhdHRlbXB0X3dhcm5zZG9yZmYoMCwwLDEpOwogICAgICAgIGlmKCFyZXMuZW1wdHkoKSl7CiAgICAgICAgICAgIGJlc3QgPSByZXM7CiAgICAgICAgICAgIGJlc3RTY29yZSA9IGNhbGNfc2NvcmUocmVzKTsKICAgICAgICB9CiAgICB9CgogICAgLy8gSWYgc3RpbGwgZW1wdHkgKHJhcmUpLCBwcm9kdWNlIHRyaXZpYWwgc2VxdWVudGlhbCBmaWxsIHRvIHNhdGlzZnkgZm9ybWF0IChidXQgY2hlY2tlciBnaXZlcyAwKQogICAgaWYoYmVzdC5lbXB0eSgpKXsKICAgICAgICBmb3IoaW50IHI9MDtyPG47KytyKXsKICAgICAgICAgICAgZm9yKGludCBjPTA7YzxuOysrYyl7CiAgICAgICAgICAgICAgICBjb3V0IDw8IChyKm4gKyBjICsgMSkgPDwgKGMrMT09bj8nXG4nOicgJyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgLy8gUHJpbnQgYmVzdCB0b3VyIChyb3ctbWFqb3IpCiAgICBmb3IoaW50IHI9MDtyPG47KytyKXsKICAgICAgICBmb3IoaW50IGM9MDtjPG47KytjKXsKICAgICAgICAgICAgY291dCA8PCBiZXN0W3IqbiArIGNdIDw8IChjKzE9PW4/J1xuJzonICcpOwogICAgICAgIH0KICAgIH0KCiAgICAvLyBJZiB5b3Ugd2FudCB0byBzZWUgdGhlIHNjb3JlIGZvciBkZWJ1Z2dpbmcsIHVuY29tbWVudDoKICAgIC8vIGNlcnIgPDwgIkJlc3RTY29yZT0iIDw8IGJlc3RTY29yZSA8PCAiXG4iOwoKICAgIHJldHVybiAwOwp9