結果
問題 | No.5007 Steiner Space Travel |
ユーザー | bond_cmprog |
提出日時 | 2022-07-30 18:56:21 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 992 ms / 1,000 ms |
コード長 | 13,731 bytes |
コンパイル時間 | 2,283 ms |
実行使用メモリ | 6,952 KB |
スコア | 6,614,872 |
最終ジャッジ日時 | 2022-07-30 18:56:57 |
合計ジャッジ時間 | 34,904 ms |
ジャッジサーバーID (参考情報) |
judge9 / judge10 |
純コード判定しない問題か言語 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 991 ms
4,904 KB |
testcase_01 | AC | 992 ms
6,948 KB |
testcase_02 | AC | 992 ms
4,904 KB |
testcase_03 | AC | 991 ms
6,952 KB |
testcase_04 | AC | 991 ms
6,948 KB |
testcase_05 | AC | 992 ms
6,948 KB |
testcase_06 | AC | 992 ms
4,904 KB |
testcase_07 | AC | 992 ms
4,904 KB |
testcase_08 | AC | 992 ms
4,904 KB |
testcase_09 | AC | 992 ms
4,904 KB |
testcase_10 | AC | 991 ms
4,900 KB |
testcase_11 | AC | 992 ms
4,904 KB |
testcase_12 | AC | 992 ms
4,904 KB |
testcase_13 | AC | 991 ms
4,904 KB |
testcase_14 | AC | 992 ms
4,904 KB |
testcase_15 | AC | 992 ms
6,948 KB |
testcase_16 | AC | 992 ms
4,904 KB |
testcase_17 | AC | 992 ms
6,952 KB |
testcase_18 | AC | 992 ms
4,900 KB |
testcase_19 | AC | 992 ms
4,900 KB |
testcase_20 | AC | 992 ms
4,904 KB |
testcase_21 | AC | 991 ms
4,904 KB |
testcase_22 | AC | 991 ms
4,900 KB |
testcase_23 | AC | 992 ms
6,948 KB |
testcase_24 | AC | 992 ms
6,952 KB |
testcase_25 | AC | 992 ms
6,948 KB |
testcase_26 | AC | 992 ms
4,904 KB |
testcase_27 | AC | 992 ms
6,948 KB |
testcase_28 | AC | 992 ms
4,904 KB |
testcase_29 | AC | 992 ms
6,952 KB |
ソースコード
#include <bits/stdc++.h> #include <sys/time.h> #pragma GCC optimize "O3,omit-frame-pointer,inline" #define ALL(v) (v).begin(), (v).end() #define OVERLOAD4(_1, _2, _3, _4, name, ...) name #define REP1(n) for(int i=0;i<n;i++) #define REP2(i, n) for(int i=0;i<n;i++) #define REP3(i, a, b) for(int i=a;i<b;i++) #define REP4(i, a, b, c) for(int i=a;i<b;i+=c) #define REP(...) OVERLOAD4(__VA_ARGS__, REP4, REP3, REP2, REP1)(__VA_ARGS__) #define ll long long using namespace std; //typedef vector<unsigned int>vec; //typedef vector<ll>vec; //typedef vector<vec> mat; typedef pair<int, int> P; typedef pair<ll,ll> LP; //const int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1}; //const int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1}; const int INF = 1000000000; const ll LINF = 1000000000000000000;//1e18 const ll MOD = 1000000007; const double PI = acos(-1.0); // const double PI = 2 * acos(0); constexpr double EPS = 1e-10; template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; } template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; } /* ----------------------- DEBUG FUNCTION ---------------------------- */ #define DUMPOUT cerr #define DEBUG_ 1 void dump_function() { DUMPOUT << ' '; } void dump_function(bool a) { DUMPOUT << a; } void dump_function(int a) { DUMPOUT << a; } void dump_function(long long a) { DUMPOUT << a; } void dump_function(char a) { DUMPOUT << a; } void dump_function(string &a) { DUMPOUT << a; } void dump_function(double a) { DUMPOUT << a; } template <class T> void dump_function(const vector<T> &); template <class T, size_t size> void dump_function(const array<T, size> &); template <class T, class L> void dump_function(const pair<T, L> &p); template <class T, size_t size> void dump_function(const T (&)[size]); template <class T> void dump_function(const vector<T> &a) { if(a.empty()) return; dump_function(a[0]); for(auto i = a.begin(); ++i != a.end();) { DUMPOUT << " "; dump_function(*i); } DUMPOUT << endl; } template <class T> void dump_function(const deque<T> &a) { if(a.empty()) return; dump_function(a[0]); for(auto i = a.begin(); ++i != a.end();) { DUMPOUT << " "; dump_function(*i); } } template <class T, size_t size> void dump_function(const array<T, size> &a) { dump_function(a[0]); for(auto i = a.begin(); ++i != a.end();) { DUMPOUT << " "; dump_function(*i); } } template <class T, class L> void dump_function(const pair<T, L> &p) { DUMPOUT << '('; dump_function(p.first); DUMPOUT << ","; dump_function(p.second); DUMPOUT << ')'; } template <class T> void dump_function(set<T> &x) { for(auto e : x) dump_function(e), DUMPOUT << " "; DUMPOUT << endl; } template <class T> void dump_function(multiset<T> &x) { for(auto e : x) dump_function(e), DUMPOUT << " "; DUMPOUT << endl; } template <class T, size_t size> void dump_function(const T (&a)[size]) { dump_function(a[0]); for(auto i = a; ++i != end(a);) { DUMPOUT << " "; dump_function(*i); } } template <class T> void dump_function(const T &a) { DUMPOUT << a; } int dump_out() { DUMPOUT << '\n'; return 0; } template <class T> int dump_out(const T &t) { dump_function(t); DUMPOUT << '\n'; return 0; } template <class Head, class... Tail> int dump_out(const Head &head, const Tail &... tail) { dump_function(head); DUMPOUT << ' '; dump_out(tail...); return 0; } #ifdef DEBUG_ #define dump(x) \ DUMPOUT << #x << ": "; \ dump_function(x); \ DUMPOUT << endl; void dumps() {} template <class T> void dumps(const T &t) { dump_function(t); DUMPOUT << " "; } template <class Head, class... Tail> void dumps(const Head &head, const Tail &... tail) { dump_function(head); DUMPOUT << ' '; dump_out(tail...); } #else #define dump(x) template <class... T> void dumps(const T &...) {} #endif /* ----------------------- DEBUG FUNCTION ---------------------------- */ constexpr ll CYCLES_PER_SEC = 2800000000; constexpr double TL = 990; double get_ms() { struct timeval t; gettimeofday(&t, NULL); return (double)t.tv_sec * 1000 + (double)t.tv_usec / 1000; } uint32_t XorShift(void) { static uint32_t x = 123456789; static uint32_t y = 362436069; static uint32_t z = 521288629; static uint32_t w = 88675123; uint32_t t; t = x ^ (x << 11); x = y; y = z; z = w; return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)); } double Prob(void){ double ret = (double)XorShift() / UINT_MAX; return ret; } struct RNG { unsigned int MT[624]; int index; RNG(int seed = 1) {init(seed);} void init(int seed = 1) {MT[0] = seed; REP(i, 1, 624) MT[i] = (1812433253UL * (MT[i-1] ^ (MT[i-1] >> 30)) + i); index = 0; } void generate() { const unsigned int MULT[] = {0, 2567483615UL}; REP(i, 227) {unsigned int y = (MT[i] & 0x8000000UL) + (MT[i+1] & 0x7FFFFFFFUL); MT[i] = MT[i+397] ^ (y >> 1); MT[i] ^= MULT[y&1]; } REP(i, 227, 623) {unsigned int y = (MT[i] & 0x8000000UL) + (MT[i+1] & 0x7FFFFFFFUL); MT[i] = MT[i-227] ^ (y >> 1); MT[i] ^= MULT[y&1]; } unsigned int y = (MT[623] & 0x8000000UL) + (MT[0] & 0x7FFFFFFFUL); MT[623] = MT[623-227] ^ (y >> 1); MT[623] ^= MULT[y&1]; } unsigned int rand() { if (index == 0) generate(); unsigned int y = MT[index]; y ^= y >> 11; y ^= y << 7 & 2636928640UL; y ^= y << 15 & 4022730752UL; y ^= y >> 18; index = index == 623 ? 0 : index + 1; return y;} inline __attribute__ ((always_inline)) int next() {return rand(); } inline __attribute__ ((always_inline)) int next(int x) {return rand() % x; } inline __attribute__ ((always_inline)) int next(int a, int b) {return a + (rand() % (b - a)); } inline __attribute__ ((always_inline)) double next_double() {return (rand() + 0.5) * (1.0 / 4294967296.0); } inline __attribute__ ((always_inline)) double next_double(double a, double b) {return a + next_double() * (b - a); } }; static RNG rng; const int N = 100; const int M = 8; const int alpha = 5; vector<int> a(N), b(N); vector<int> c(M), d(M); vector<int> ans; vector<vector<int>> dist(N+M, vector<int>(N+M)); double start = 0.0; vector<int> labels(N); vector<int> clusters(M); // cluster[i]に含まれる点の個数 namespace yukicoder_score_contest2{ void init(){ REP(i,N) ans.emplace_back(i); // calc_dist REP(i,N+M) REP(j,N+M) { int ai = (i < N ? a[i] : c[i-N]); int aj = (j < N ? a[j] : c[j-N]); int bi = (i < N ? b[i] : d[i-N]); int bj = (j < N ? b[j] : d[j-N]); dist[i][j] = alpha * alpha * ((ai - aj) * (ai - aj) + (bi - bj) * (bi - bj)); } } void input(){ int _N, _M; cin >> _N >> _M; start = get_ms(); REP(i,N) cin >> a[i] >> b[i]; } void output() { // REP(i,M) cout << c[i] << " " << d[i] << "\n"; int idx1 = 0; int sz = ans.size(); cout << sz+1 << endl; REP(i,sz) if(ans[i] == 0) idx1 = i; REP(i,sz) { if(ans[(idx1+i)%sz] >= N) cout << "2 " << ans[(idx1+i)%sz] - N + 1 << "\n"; else cout << "1 " << ans[(idx1+i)%sz] + 1 << "\n"; } cout << "1 " << ans[idx1] + 1 << endl; } int calc_diff(int i0, int i1) { const int sz = ans.size(); int j0 = (i0 + sz - 1) % sz; int j1 = (i1 + 1) % sz; const double d_cur = dist[ans[i0]][ans[j0]] + dist[ans[i1]][ans[j1]]; const double d_next = dist[ans[i0]][ans[j1]] + dist[ans[i1]][ans[j0]]; return d_cur - d_next; } void k_means() { REP(i,N) labels[i] = i % M; const int MAX_ITER = 1000; int iter = 0; bool update = true; while(iter < MAX_ITER and update) { update = false; REP(i,M) c[i] = d[i] = clusters[i] = 0; REP(i,N) { int label = labels[i]; c[label] += a[i]; d[label] += b[i]; clusters[label]++; } REP(i,M) if(clusters[i] > 0) c[i] /= clusters[i], d[i] /= clusters[i]; REP(i,N) { int mi = INF; int new_cluster = labels[i]; REP(j,M) if(chmin(mi, (a[i] - c[j]) * (a[i] - c[j]) + (b[i] - b[j]) * (b[i] - b[j]))) new_cluster = j; if(labels[i] != new_cluster) { update = true; labels[i] = new_cluster; } } iter++; } dump(clusters); dump(iter); } void output_k_means() { REP(i,M) cout << c[i] << " " << d[i] << endl; } void SA(){ int iter = 0; int move = 0; int last_move = 0; const double T_init = 260; const double T_end = 50; double T = T_init; for(iter = 1 ; ; iter++) { int i0 = rng.next(N); int i1 = rng.next(N); if(i0 > i1) swap(i0, i1); const int diff = calc_diff(i0, i1); if(diff > 0 or exp(diff / T) > (double)rng.next(INF+9)) { reverse(ans.begin() + i0, ans.begin() + i1 + 1); move++; last_move = iter; } if(iter % 1000 == 0) { double elapsed = get_ms() - start; if(elapsed > 600) break; T = (T_end - T_init) / TL * elapsed + T_init; } } dump(iter); dump(move); dump(last_move); } void SA2(){ int iter = 0; int move = 0; int last_move = 0; const double T_init = 260; const double T_end = 50; double T = (T_end - T_init) / TL * (get_ms() - start) + T_init; for(iter = 1 ; ; iter++) { int i0 = rng.next(ans.size()); int i1 = rng.next(ans.size()); if(i0 > i1) swap(i0, i1); const int diff = calc_diff(i0, i1); if(diff > 0 or exp(diff / T) > (double)rng.next(INF+9)) { reverse(ans.begin() + i0, ans.begin() + i1 + 1); move++; last_move = iter; } if(iter % 1000 == 0) { double elapsed = get_ms() - start; if(elapsed > TL) break; T = (T_end - T_init) / TL * elapsed + T_init; } } dump(iter); dump(move); dump(last_move); } void greedy() { // dump(ans); // REP(i,M) { // int ma = 0; // int idx = -1; // int sz = ans.size(); // int best_mx = -1; // int best_my = -1; // dump(sz); // REP(j,sz) { // int i0 = ans[j]; // int i1 = ans[(j+1)%sz]; // int x_i0 = (i0 >= N ? c[i0 - N] : a[i0]); // int y_i0 = (i0 >= N ? d[i0 - N] : b[i0]); // int x_i1 = (i1 >= N ? c[i1 - N] : a[i1]); // int y_i1 = (i1 >= N ? d[i1 - N] : b[i1]); // int mx = (x_i0 + x_i1) / 2; // int my = (y_i0 + y_i1) / 2; // int d_cur = (x_i0 - x_i1) * (x_i0 - x_i1) + (y_i0 - y_i1) * (y_i0 - y_i1); // if(i0 < N) d_cur *= alpha; // if(i1 < N) d_cur *= alpha; // int d_next = (i0 < N ? alpha : 1) * ((x_i0 - mx) * (x_i0 - mx) + (y_i0 - my) * (y_i0 - my)); // d_next += (i1 < N ? alpha : 1) * ((x_i1 - mx) * (x_i1 - mx) + (y_i1 - my) * (y_i1 - my)); // if(chmax(ma, d_cur - d_next)) { // idx = j; // best_mx = mx; // best_my = my; // } // } // if(idx) { // ans.insert(ans.begin() + idx + 1, i + N); // c[i] = best_mx; // d[i] = best_my; // } // } REP(j,ans.size()) { int i0 = ans[j]; int i1 = ans[(j+1)%(int)ans.size()]; if(i0 == i1) continue; if(i0 >= N or i1 >= N) continue; if(labels[i0] != labels[i1]) continue; int x_i0 = (i0 >= N ? c[i0 - N] : a[i0]); int y_i0 = (i0 >= N ? d[i0 - N] : b[i0]); int x_i1 = (i1 >= N ? c[i1 - N] : a[i1]); int y_i1 = (i1 >= N ? d[i1 - N] : b[i1]); int mx = c[labels[i0]]; int my = d[labels[i0]]; int d_cur = (x_i0 - x_i1) * (x_i0 - x_i1) + (y_i0 - y_i1) * (y_i0 - y_i1); if(i0 < N) d_cur *= alpha; if(i1 < N) d_cur *= alpha; int d_next = (i0 < N ? alpha : 1) * ((x_i0 - mx) * (x_i0 - mx) + (y_i0 - my) * (y_i0 - my)); d_next += (i1 < N ? alpha : 1) * ((x_i1 - mx) * (x_i1 - mx) + (y_i1 - my) * (y_i1 - my)); if(d_cur - d_next > 0) { ans.insert(ans.begin() + j + 1, labels[i0] + N); j++; } } } void main(){ input(); k_means(); output_k_means(); init(); SA(); greedy(); SA2(); output(); } } int main(){ cin.tie(0); ios::sync_with_stdio(false); yukicoder_score_contest2::main(); }