結果
| 問題 |
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;
}