結果
問題 |
No.3131 Twin Slide Puzzles
|
ユーザー |
👑 |
提出日時 | 2025-03-05 22:14:03 |
言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 384 ms / 4,000 ms |
コード長 | 4,909 bytes |
コンパイル時間 | 6,384 ms |
コンパイル使用メモリ | 334,740 KB |
実行使用メモリ | 45,656 KB |
最終ジャッジ日時 | 2025-06-20 02:23:20 |
合計ジャッジ時間 | 27,028 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 59 |
ソースコード
#include <bits/stdc++.h> #include <atcoder/all> using namespace std; using namespace atcoder; using ll = long long; int N; vector<vector<int>> A; vector<int> serialize(const vector<vector<int>>& X) { vector<int> ret; for (const auto &row : X) for (int x : row) ret.push_back(x); return ret; } int calc_parity(const vector<vector<int>>& X) { for (int i = 0; i < (int)X.size(); i++){ for (int j = 0; j < (int)X[i].size(); j++){ if (X[i][j] == 0) return (i + j) % 2; } } return 0; } ll calc_inversion(const vector<int>& arr) { int MAX = *max_element(arr.begin(), arr.end()); fenwick_tree<int> bit(MAX + 1); ll result = 0; for (int a : arr) { result += bit.sum(0, MAX + 1) - bit.sum(0, a + 1); bit.add(a, 1); } return result; } bool is_valid(const vector<vector<int>>& X) { int parity = calc_parity(X); vector<int> ser = serialize(X); ll inversion = calc_inversion(ser); return parity == (inversion % 2); } ll fun(const vector<vector<int>>& X) { ll res = 0; for (int i = 0; i < (int)X.size(); i++){ for (int j = 0; j < (int)X[i].size(); j++){ res += (ll)A[i][j] * X[i][j]; } } return res; } bool matrices_equal(const vector<vector<int>>& X, const vector<vector<int>>& Y) { if (X.size() != Y.size()) return false; for (size_t i = 0; i < X.size(); i++){ if (X[i].size() != Y[i].size()) return false; for (size_t j = 0; j < X[i].size(); j++){ if (X[i][j] != Y[i][j]) return false; } } return true; } int main(){ cin >> N; A.resize(N, vector<int>(N)); for (int i = 0; i < N; i++){ for (int j = 0; j < N; j++){ cin >> A[i][j]; } } unordered_map<ll, vector<vector<int>>> val; if (N <= 3) { vector<int> perm(N * N); for (int i = 0; i < N * N; i++) perm[i] = i; do { vector<vector<int>> X(N, vector<int>(N)); for (int i = 0; i < N; i++){ for (int j = 0; j < N; j++){ X[i][j] = perm[i * N + j]; } } if (!is_valid(X)) continue; ll f = fun(X); if (val.find(f) != val.end() && !matrices_equal(X, val[f])) { cout << "Yes" << "\n"; for (auto &row : val[f]) { for (int x : row) cout << x << " "; cout << "\n"; } for (auto &row : X) { for (int x : row) cout << x << " "; cout << "\n"; } return 0; } val[f] = X; } while (next_permutation(perm.begin(), perm.end())); } else { const int M = 16; // 4**2 vector<int> perm(M); for (int i = 0; i < M; i++) perm[i] = i; random_device rd; mt19937 g(rd()); while (true) { shuffle(perm.begin(), perm.end(), g); vector<vector<int>> X; for (int i = 0; i < M; i += N) { vector<int> row; for (int j = i; j < i + N && j < M; j++) { row.push_back(perm[j]); } X.push_back(row); } if (!is_valid(X)) continue; ll f = fun(X); if (val.find(f) != val.end() && !matrices_equal(X, val[f])) { cout << "Yes" << "\n"; for (int i = 0; i < N; i++){ for (int j = 0; j < N; j++){ if (i * N + j < M) { if (i < (int)val[f].size() && j < (int)val[f][i].size()) cout << val[f][i][j] << " "; else cout << i * N + j << " "; } else { cout << i * N + j << " "; } } cout << "\n"; } for (int i = 0; i < N; i++){ for (int j = 0; j < N; j++){ if (i * N + j < M) { if (i < (int)X.size() && j < (int)X[i].size()) cout << X[i][j] << " "; else cout << i * N + j << " "; } else { cout << i * N + j << " "; } } cout << "\n"; } return 0; } val[f] = X; } } cout << "No" << "\n"; return 0; }