結果

問題 No.5007 Steiner Space Travel
ユーザー bond_cmprogbond_cmprog
提出日時 2022-07-30 15:31:59
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 994 ms / 1,000 ms
コード長 10,382 bytes
コンパイル時間 2,224 ms
実行使用メモリ 4,088 KB
スコア 7,069,656
最終ジャッジ日時 2022-07-30 15:32:34
合計ジャッジ時間 35,021 ms
ジャッジサーバーID
(参考情報)
judge11 / judge12
純コード判定しない問題か言語
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 994 ms
3,800 KB
testcase_01 AC 993 ms
3,920 KB
testcase_02 AC 993 ms
3,984 KB
testcase_03 AC 994 ms
3,988 KB
testcase_04 AC 993 ms
3,984 KB
testcase_05 AC 994 ms
3,932 KB
testcase_06 AC 994 ms
3,936 KB
testcase_07 AC 994 ms
4,064 KB
testcase_08 AC 994 ms
3,896 KB
testcase_09 AC 994 ms
3,996 KB
testcase_10 AC 994 ms
3,944 KB
testcase_11 AC 994 ms
3,884 KB
testcase_12 AC 993 ms
4,064 KB
testcase_13 AC 993 ms
4,088 KB
testcase_14 AC 994 ms
4,068 KB
testcase_15 AC 994 ms
3,920 KB
testcase_16 AC 994 ms
4,068 KB
testcase_17 AC 993 ms
3,796 KB
testcase_18 AC 994 ms
3,952 KB
testcase_19 AC 994 ms
4,040 KB
testcase_20 AC 994 ms
3,932 KB
testcase_21 AC 994 ms
3,884 KB
testcase_22 AC 994 ms
3,996 KB
testcase_23 AC 993 ms
3,988 KB
testcase_24 AC 993 ms
3,800 KB
testcase_25 AC 994 ms
3,840 KB
testcase_26 AC 994 ms
3,940 KB
testcase_27 AC 994 ms
4,032 KB
testcase_28 AC 994 ms
3,920 KB
testcase_29 AC 994 ms
4,032 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#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, vector<int>(N));
double start = 0.0;
namespace yukicoder_score_contest2{

    void init(){
        REP(i,N) ans.emplace_back(i);

        // calc_dist
        REP(i,N) REP(j,N) dist[i][j] = alpha * alpha * ((a[i] - a[j]) * (a[i] - a[j]) + (b[i] - b[j]) * (b[i] - b[j]));
    }

    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) {
        int j0 = (i0  + N - 1) % N;
        int j1 = (i1 + 1) % N;
        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 SA(){
        int iter = 0;
        int move = 0;
        int last_move = 0;
        const double T_init = 80;
        const double T_end = 10;
        double T = 100;

        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 > 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) {
                dump(best_mx);
                dump(best_my);
                dump(ans[idx]);
                dump(ans[(idx+1)%sz]);
                ans.insert(ans.begin() + idx + 1, i + N);
                c[i] = best_mx;
                d[i] = best_my;
                dumps(i, idx);
                dump(ans);
            }
        }
    }
    
    void main(){
        input();
        init();
        SA();
        greedy();
        output();
    }
}

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    yukicoder_score_contest2::main();
}
0