結果

問題 No.5020 Averaging
ユーザー t33f
提出日時 2024-02-25 15:06:36
言語 C++17(gcc12)
(gcc 12.3.0 + boost 1.87.0)
結果
AC  
実行時間 953 ms / 1,000 ms
コード長 4,303 bytes
コンパイル時間 1,194 ms
コンパイル使用メモリ 111,936 KB
実行使用メモリ 6,676 KB
スコア 38,118,471
最終ジャッジ日時 2024-02-25 15:07:28
合計ジャッジ時間 51,540 ms
ジャッジサーバーID
(参考情報)
judge15 / judge10
純コード判定しない問題か言語
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other AC * 50
権限があれば一括ダウンロードができます

ソースコード

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

#include <random>
#include <chrono>
#include <cmath>
#include <vector>
#include <cassert>
#include <iostream>
using namespace std;
constexpr int N = 45;
constexpr int op_max = 50;
long long A[N], B[N];
constexpr int timelimit = 950;
class Timer {
chrono::system_clock::time_point start_time = chrono::system_clock::now();
public:
Timer() {}
long long get_elapsed_time() {
auto diff = chrono::system_clock::now() - start_time;
return chrono::duration_cast<chrono::milliseconds>(diff).count();
}
} timer;
void write_ans(const vector<pair<int, int>> &ans) {
cout << ans.size() << '\n';
for (const auto &[a, b] : ans)
cout << a + 1 << ' ' << b + 1 << '\n';
}
int calc_score(const vector<pair<int, int>> &ans, bool print_result = false) {
long long a[N], b[N];
copy(begin(A), end(A), begin(a));
copy(begin(B), end(B), begin(b));
for (const auto &[i, j] : ans) {
long long x = (a[i] + a[j]) / 2;
long long y = (b[i] + b[j]) / 2;
a[i] = a[j] = x;
b[i] = b[j] = y;
}
if (print_result)
for (int i = 0; i < N; ++i) cerr << a[i] << ' ' << b[i] << '\n';
constexpr long long target = (long long)5e17;
const long long diff = max(abs(target - a[0]), abs(target - b[0]));
return diff > 0 ?
int(floor(2'000'000 - 100'000 * log10(diff + 1))) :
2'000'050 - int(ans.size());
}
int main() {
{ int n; cin >> n; assert(n == N); }
for (int i = 0; i < N; ++i) cin >> A[i] >> B[i];
vector<pair<int, int>> ans;
int score = calc_score(ans);
vector<pair<int, int>> best_ans = ans;
int best_score = score;
mt19937 mt;
int iter = 0;
const auto accept = [&](int diff) {
if (diff >= 0) {
return true;
} else {
const double start_temp = 10000;
const double end_temp = 1000;
const double progress = double(timer.get_elapsed_time()) / timelimit;
const double temp = start_temp + progress * (end_temp - start_temp);
const double prob = exp(diff / temp);
return bernoulli_distribution(prob)(mt);
}
};
while (timer.get_elapsed_time() < timelimit) {
if (ans.empty() || (ans.size() < op_max && mt() % 2 == 0)) {
const int i = int(mt() % (1 + ans.size()));
const int p = int(mt() % N);
const int q = int(mt() % N);
if (p >= q) continue;
iter++;
ans.insert(ans.begin() + i, {p, q});
const int tmp_score = calc_score(ans);
if (accept(tmp_score - score)) {
// if (tmp_score > score)
// cerr << iter << " " << tmp_score << '\n';
score = tmp_score;
} else {
ans.erase(ans.begin() + i);
}
} else if (mt() % 2 == 0) {
const size_t i = mt() % ans.size();
const auto old = ans[i];
const int p = int(mt() % N);
const int q = int(mt() % N);
if (p >= q || (old.first == p && old.second == q)) continue;
iter++;
ans[i] = {p, q};
const int tmp_score = calc_score(ans);
if (accept(tmp_score - score)) {
// if (tmp_score > score)
// cerr << iter << " " << tmp_score << '\n';
score = tmp_score;
} else {
ans[i] = old;
}
} else {
const int i = int(mt() % ans.size());
const auto old = ans[size_t(i)];
ans.erase(ans.begin() + i);
iter++;
const int tmp_score = calc_score(ans);
if (tmp_score >= score) {
// if (tmp_score > score)
// cerr << iter << " " << tmp_score << '\n';
score = tmp_score;
} else {
ans.insert(ans.begin() + i, old);
}
}
if (best_score < score) {
cerr << iter << " " << score << '\n';
best_score = score;
best_ans = ans;
}
if (iter % 100000 == 0) cerr << ' ' << iter << ' ' << score << endl;
}
cerr << "score = " << best_score << endl;
calc_score(ans, true);
write_ans(best_ans);
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0