結果
問題 |
No.3131 Twin Slide Puzzles
|
ユーザー |
👑 |
提出日時 | 2025-04-25 21:51:52 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 196 ms / 4,000 ms |
コード長 | 4,423 bytes |
コンパイル時間 | 1,592 ms |
コンパイル使用メモリ | 161,396 KB |
実行使用メモリ | 52,688 KB |
最終ジャッジ日時 | 2025-06-20 02:44:07 |
合計ジャッジ時間 | 14,476 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 59 |
コンパイルメッセージ
main.cpp: In function ‘int main()’: main.cpp:139:12: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 139 | scanf("%lld", &A[i]); | ~~~~~^~~~~~~~~~~~~~~
ソースコード
#include <cassert> #include <cmath> #include <cstdint> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <bitset> #include <chrono> #include <complex> #include <deque> #include <functional> #include <iostream> #include <limits> #include <map> #include <numeric> #include <queue> #include <random> #include <set> #include <sstream> #include <string> #include <unordered_map> #include <unordered_set> #include <utility> #include <vector> using namespace std; using Int = long long; template <class T1, class T2> ostream &operator<<(ostream &os, const pair<T1, T2> &a) { return os << "(" << a.first << ", " << a.second << ")"; }; template <class T> ostream &operator<<(ostream &os, const vector<T> &as) { const int sz = as.size(); os << "["; for (int i = 0; i < sz; ++i) { if (i >= 256) { os << ", ..."; break; } if (i > 0) { os << ", "; } os << as[i]; } return os << "]"; } template <class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; } template <class T> bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; } template <class T> bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; } #define COLOR(s) ("\x1b[" s "m") // cannot use count // no move constructor (==> use pointer for merge tech) // unordered_set by value: __gnu_pbds::null_type // no erase(iterator) #include <ext/pb_ds/assoc_container.hpp> using __gnu_pbds::gp_hash_table; // https://codeforces.com/blog/entry/62393 #include <chrono> struct Hash { static uint64_t splitmix64(uint64_t x) { // http://xorshift.di.unimi.it/splitmix64.c x += 0x9e3779b97f4a7c15; x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; x = (x ^ (x >> 27)) * 0x94d049bb133111eb; return x ^ (x >> 31); } size_t operator()(uint64_t x) const { static const uint64_t FIXED_RANDOM = std::chrono::steady_clock::now().time_since_epoch().count(); return splitmix64(x + FIXED_RANDOM); } size_t operator()(const pair<int, int> &a) const { return operator()((uint64_t)a.first << 32 | a.second); } }; template <class K> using Set = gp_hash_table<K, __gnu_pbds::null_type, Hash>; template <class K, class V> using Map = gp_hash_table<K, V, Hash>; #include <chrono> #ifdef LOCAL mt19937_64 rng(58); #else mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count()); #endif vector<int> uf; int root(int u) { return (uf[u] < 0) ? u : (uf[u] = root(uf[u])); } bool connect(int u, int v) { u = root(u); v = root(v); if (u == v) return false; if (uf[u] > uf[v]) swap(u, v); uf[u] += uf[v]; uf[v] = u; return true; } int N; vector<Int> A; pair<basic_string<int>, basic_string<int>> solve() { const int L = min(N*N, 14); uf.resize(L); Map<Int, basic_string<int>> vis; basic_string<int> ps(L, -1), qs; auto check = [&]() -> bool { fill(uf.begin(), uf.end(), -1); int sig = +1; for (int i = 0; i < L; ++i) if (connect(i, ps[i])) sig = -sig; for (int i = 0; i < L; ++i) if (ps[i] == 0) { const int x = i / N, y = i % N; if (sig != ((x+y)&1?-1:+1)) return false; } Int sum = 0; for (int i = 0; i < L; ++i) sum += A[i] * ps[i]; auto it = vis.find(sum); if (it != vis.end()) { if (ps == it->second) return false; qs = it->second; return true; } else { vis[sum] = ps; return false; } }; for (int i = 0; i < L; ++i) ps[i] = i; if (N <= 3) { do { if (check()) return make_pair(ps, qs); } while (next_permutation(ps.begin(), ps.end())); } else { for (; ; ) { for (int i = 0; i < L; ++i) swap(ps[rng() % (i + 1)], ps[i] = i); if (check()) return make_pair(ps, qs); } } return {}; } int main() { for (; ~scanf("%d", &N); ) { A.resize(N*N); for (int i = 0; i < N*N; ++i) { scanf("%lld", &A[i]); } auto ans = solve(); if (ans.first.size()) { puts("Yes"); auto print = [&](basic_string<int> &ps) -> void { const int psLen = ps.size(); ps.resize(N*N); for (int i = psLen; i < N*N; ++i) ps[i] = i; for (int x = 0; x < N; ++x) { for (int y = 0; y < N; ++y) { if (y) printf(" "); printf("%d", ps[x * N + y]); } puts(""); } }; print(ans.first); print(ans.second); } else { puts("No"); } } return 0; }