結果

問題 No.5020 Averaging
ユーザー siman
提出日時 2024-02-25 13:40:52
言語 C++23
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 955 ms / 1,000 ms
コード長 4,509 bytes
コンパイル時間 1,609 ms
コンパイル使用メモリ 145,308 KB
実行使用メモリ 6,676 KB
スコア 14,749,563
最終ジャッジ日時 2024-02-25 13:41:44
合計ジャッジ時間 51,991 ms
ジャッジサーバーID
(参考情報)
judge11 / judge15
純コード判定しない問題か言語
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other AC * 50
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

#include <cassert>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <climits>
#include <map>
#include <queue>
#include <set>
#include <cstring>
#include <vector>
#include <random>
#include <chrono>
using namespace std;
typedef long long ll;
constexpr int N = 45;
constexpr int T = 50;
constexpr double TIME_LIMIT = 0.95;
constexpr ll
BASE_SCORE = 500000000000000000;
ll A[N];
ll B[N];
ll A_copy[N];
ll B_copy[N];
class Xorshift {
public:
Xorshift(uint64_t seed = 88675123) {
_x = 123456789;
_y = 362436069;
_z = 521288629;
_w = seed;
for (int i = 0; i < 100; ++i) {
next();
}
}
uint64_t next(uint64_t a, uint64_t b) {
return a + (next() % (b - a + 1));
}
uint64_t next() {
uint64_t t = _x ^ (_x << 11);
_x = _y;
_y = _z;
_z = _w;
_w = (_w ^ (_w >> 19)) ^ (t ^ (t >> 8));
return _w;
}
double random_double() {
return static_cast<double>(next()) / UINT64_MAX;
}
double random_double(double a, double b) {
return a + (b - a) * random_double();
}
private:
uint64_t _x, _y, _z, _w;
};
class Timer {
public:
Timer() {
begin();
_duration = 0.0;
}
void begin() {
_start_at = chrono::system_clock::now();
}
double get_time() {
chrono::system_clock::time_point end_at = chrono::system_clock::now();
_duration = chrono::duration_cast<std::chrono::nanoseconds>(end_at - _start_at).count();
return _duration / 1000000000.0;
}
double progress(double time_limit) {
return get_time() / time_limit;
}
private:
chrono::system_clock::time_point _start_at;
double _duration;
};
Xorshift g_rng;
class Solver {
public:
void run() {
load_data();
setup();
auto res = sa();
/*
cout << N << endl;
for (int i = 0; i < N; ++i) {
cout << A[i] << " " << B[i] << endl;
}
*/
cout << res.size() << endl;
for (int i = 0; i < T; ++i) {
cout << res[i].first << " " << res[i].second << endl;
}
}
private:
void load_data() {
int _N;
cin >> _N;
for (int i = 0; i < N; ++i) {
cin >> A[i] >> B[i];
}
}
void setup() {
}
vector <pair<int, int>> sa(double time_limit = TIME_LIMIT) {
Timer timer;
int U[T], V[T];
for (int i = 0; i < T; ++i) {
int u, v;
do {
u = g_rng.next(0, N - 1);
v = g_rng.next(0, N - 1);
} while (u == v);
U[i] = u;
V[i] = v;
}
int best_U[T], best_V[T];
memcpy(best_U, U, sizeof(U));
memcpy(best_V, V, sizeof(V));
int cur_score = calc_score_full(U, V);
int best_score = cur_score;
double cur_time = timer.get_time();
double total_diff = 0.0;
double t = 0.1;
ll R = 100000000;
int try_count = 0;
while (cur_time < time_limit) {
cur_time = timer.get_time();
double remain_time = (time_limit - cur_time) / time_limit;
int score = calc_score_full(U, V);
double diff_score = cur_score - score;
total_diff += fabs(diff_score);
if (diff_score > 0 || (g_rng.next() % R < R * exp(diff_score / (t * pow(remain_time, 2))))) {
cur_score = score;
if (best_score < score) {
best_score = score;
memcpy(best_U, U, sizeof(U));
memcpy(best_V, V, sizeof(V));
}
} else {
}
++try_count;
double average_diff = total_diff / try_count;
t = 0.25 * remain_time * average_diff;
}
fprintf(stderr, "try_count: %d, best_score: %d\n", try_count, best_score);
vector <pair<int, int>> res;
for (int i = 0; i < T; ++i) {
res.emplace_back(make_pair(best_U[i] + 1, best_V[i] + 1));
}
return res;
}
int calc_score_full(int *U, int *V) {
memcpy(A_copy, A, sizeof(A));
memcpy(B_copy, B, sizeof(B));
for (int i = 0; i < N; ++i) {
int u = U[i];
int v = V[i];
ll sum_a = A_copy[u] + A_copy[v];
ll sum_b = B_copy[u] + B_copy[v];
A_copy[u] = sum_a >> 1;
A_copy[v] = sum_a >> 1;
B_copy[u] = sum_b >> 1;
B_copy[v] = sum_b >> 1;
}
ll diff_A = abs(BASE_SCORE - A_copy[0]);
ll diff_B = abs(BASE_SCORE - B_copy[0]);
ll max_diff = max(diff_A, diff_B);
// Score = (int)(2000000.0 - 100000.0 * math.log10(1.0 * max(ErrorA, ErrorB) + 1.0))
int score = (int) (2000000.0 - 100000.0 * log10(1.0 * max_diff + 1.0));
return score;
}
};
int main() {
std::cin.tie(0)->sync_with_stdio(0);
Solver solver;
solver.run();
return 0;
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0