結果

問題 No.5020 Averaging
ユーザー neterukunneterukun
提出日時 2024-02-25 14:09:41
言語 C++23
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 953 ms / 1,000 ms
コード長 6,075 bytes
コンパイル時間 2,230 ms
コンパイル使用メモリ 180,228 KB
実行使用メモリ 6,676 KB
スコア 38,219,641
最終ジャッジ日時 2024-02-25 14:10:34
合計ジャッジ時間 52,321 ms
ジャッジサーバーID
(参考情報)
judge15 / judge13
純コード判定しない問題か言語
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 952 ms
6,676 KB
testcase_01 AC 952 ms
6,676 KB
testcase_02 AC 951 ms
6,676 KB
testcase_03 AC 952 ms
6,676 KB
testcase_04 AC 952 ms
6,676 KB
testcase_05 AC 952 ms
6,676 KB
testcase_06 AC 952 ms
6,676 KB
testcase_07 AC 952 ms
6,676 KB
testcase_08 AC 952 ms
6,676 KB
testcase_09 AC 952 ms
6,676 KB
testcase_10 AC 953 ms
6,676 KB
testcase_11 AC 952 ms
6,676 KB
testcase_12 AC 952 ms
6,676 KB
testcase_13 AC 952 ms
6,676 KB
testcase_14 AC 952 ms
6,676 KB
testcase_15 AC 953 ms
6,676 KB
testcase_16 AC 951 ms
6,676 KB
testcase_17 AC 952 ms
6,676 KB
testcase_18 AC 952 ms
6,676 KB
testcase_19 AC 952 ms
6,676 KB
testcase_20 AC 953 ms
6,676 KB
testcase_21 AC 952 ms
6,676 KB
testcase_22 AC 951 ms
6,676 KB
testcase_23 AC 952 ms
6,676 KB
testcase_24 AC 953 ms
6,676 KB
testcase_25 AC 953 ms
6,676 KB
testcase_26 AC 952 ms
6,676 KB
testcase_27 AC 951 ms
6,676 KB
testcase_28 AC 953 ms
6,676 KB
testcase_29 AC 953 ms
6,676 KB
testcase_30 AC 952 ms
6,676 KB
testcase_31 AC 952 ms
6,676 KB
testcase_32 AC 951 ms
6,676 KB
testcase_33 AC 952 ms
6,676 KB
testcase_34 AC 952 ms
6,676 KB
testcase_35 AC 952 ms
6,676 KB
testcase_36 AC 952 ms
6,676 KB
testcase_37 AC 952 ms
6,676 KB
testcase_38 AC 951 ms
6,676 KB
testcase_39 AC 952 ms
6,676 KB
testcase_40 AC 953 ms
6,676 KB
testcase_41 AC 952 ms
6,676 KB
testcase_42 AC 952 ms
6,676 KB
testcase_43 AC 951 ms
6,676 KB
testcase_44 AC 952 ms
6,676 KB
testcase_45 AC 953 ms
6,676 KB
testcase_46 AC 952 ms
6,676 KB
testcase_47 AC 952 ms
6,676 KB
testcase_48 AC 952 ms
6,676 KB
testcase_49 AC 952 ms
6,676 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <chrono>
#include <cmath>
#include <cstdint>
#include <cstring>
#include <deque>
#include <iostream>
#include <map>
#include <memory>
#include <queue>
#include <random>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;

#define REP(i, n) for (int i = 0; i < (int)(n); ++ (i))
#define REP3(i, m, n) for (int i = (m); (i) < (int)(n); ++ (i))

uint64_t rand64() {
    static uint64_t x = 88172645463325252ULL;
    x = x ^ (x << 7);
    return x = x ^ (x >> 9);
}

double rand_p() { return rand64() * (1.0 / UINT64_MAX); }

using namespace std::chrono;
using namespace std;
struct Timer {
    system_clock::time_point start;

    Timer() { reset(); }

    void reset() { start = system_clock::now(); }

    double sec_elapsed() const {
        return duration_cast<milliseconds>(system_clock::now() - start).count() / 1000.0;
    }
};

constexpr int N = 45;
constexpr int M = 50;
long long A[N];
long long B[N];

void input() {
    int tmp;
    std::cin >> tmp;
    REP(i, N) {
        std::cin >> A[i] >> B[i];
    }
}

struct State {
    std::vector<std::pair<int, int>> operations;
    std::vector<long long> testA;
    std::vector<long long> testB;
        
    int old_index, old_i, old_j;

    State() {
        REP(k, M) {
            int i = rand64() % N;
            int j = rand64() % N;
            operations.emplace_back(i, j);
        }
        testA.resize(N);
        testB.resize(N);
    }

    void modify() {
        int index = rand64() % M;
        int i = rand64() % N;
        int j = rand64() % N;
        modify(index, i, j);
    }
    
    void modify(int index, int i, int j) {
        old_index = index;
        old_i = operations[index].first;
        old_j = operations[index].second;
        operations[index] = std::make_pair(i, j);
    }

    void rollback() {
        operations[old_index] = std::make_pair(old_i, old_j);
    }

    long long calc_score() {
        REP(i, N) {
            testA[i] = A[i];
            testB[i] = B[i];
        }

        for (auto &op : operations) {
            int i = op.first;
            int j = op.second;
            long long avgA = (testA[i] + testA[j]) / 2LL;
            long long avgB = (testB[i] + testB[j]) / 2LL;
            testA[i] = avgA;
            testA[j] = avgA;
            testB[i] = avgB;
            testB[j] = avgB;
        }

        long long ErrorA = abs(500000000000000000LL - testA[0]);
        long long ErrorB = abs(500000000000000000LL - testB[0]);
        long long Score = (long long)(2000000.0L - 100000.0L * log10(1.0L * max(ErrorA, ErrorB) + 1.0L));
        return Score;
    }
    
    void print() {
        int invalid_count = 0;
        REP(i, M) {
            int a = operations[i].first;
            int b = operations[i].second;
            if (a == b) {
                invalid_count += 1;
            }
        }
        std::cout << M - invalid_count << std::endl;
        REP(i, M) {
            int a = operations[i].first;
            int b = operations[i].second;
            if (a != b) {
                std::cout << a + 1<< " " << b + 1 << std::endl;
            }
        }
    }
};


State annealing(State cur_state, const Timer &timer, const double time_limit) {
    // 温度設定
    const double start_temp = 1e0;
    const double end_temp = 1e0;

    double inv_temp = 1.0 / start_temp;

    int iter_count = 0;
    long long cur_score = cur_state.calc_score();

    State best_state = cur_state;
    long long best_score = best_state.calc_score();
    
    double start_time = timer.sec_elapsed();
    double now = start_time;

    while (now < time_limit) {
      
        if (iter_count & 1024) {
            now = timer.sec_elapsed();
            const double time_ratio = (now - start_time) / (time_limit - start_time);
            // const double temp = start_temp + (end_temp - start_temp) * time_ratio;  // 線形
            const double temp = start_temp * std::pow(end_temp / start_temp, time_ratio);  // pow 	
            inv_temp = 1.0 / temp;
        }

        cur_state.modify();
        long long new_score = cur_state.calc_score();

        double prob = std::exp((new_score - cur_score) * inv_temp);

        if (prob > rand_p()) {
            cur_score = new_score;
        } else {
            cur_state.rollback();
        }
        if (cur_score > best_score) {
            best_score = cur_score;
            best_state = cur_state;
        }
        iter_count += 1;
    }
    std::cerr << iter_count << std::endl;
    return best_state;
}


State kick(State cur_state, const Timer &timer, const double time_limit) {
    int iter_count = 0;
    long long cur_score = cur_state.calc_score();

    State best_state = cur_state;
    long long best_score = best_state.calc_score();
    
    double start_time = timer.sec_elapsed();
    double now = start_time;

    while (now < time_limit) {

        now = timer.sec_elapsed();

        bool update = false;

        REP(index, M) REP(i, N) REP3(j, i + 1, N) {
            cur_state.modify(index, i, j);
            long long new_score = cur_state.calc_score();
            if (new_score > cur_score) {
                cur_score = new_score;
                update = true;
            } else {
                cur_state.rollback();
            }
        }
        
        if (cur_score > best_score) {
            best_score = cur_score;
            best_state = cur_state;
        }
        
        if (!update) {
            // kickする
            cur_state = best_state;
            cur_state.modify();
            cur_state.modify();
            cur_score = cur_state.calc_score();
        }

        iter_count += 1;
    }
    std::cerr << iter_count << std::endl;
    return best_state;
}

int main() {
    input();
    Timer timer;

    State state;

    state = annealing(state, timer, 0.95);
    //state = kick(state, timer, 0.95);

    std::cerr << state.calc_score() << std::endl;
    state.print();
}
0