結果
| 問題 |
No.5020 Averaging
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2024-02-25 16:44:18 |
| 言語 | C++17(gcc12) (gcc 12.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 903 ms / 1,000 ms |
| コード長 | 5,934 bytes |
| コンパイル時間 | 3,279 ms |
| コンパイル使用メモリ | 223,172 KB |
| 実行使用メモリ | 6,676 KB |
| スコア | 20,993,879 |
| 最終ジャッジ日時 | 2024-02-25 16:46:32 |
| 合計ジャッジ時間 | 51,014 ms |
|
ジャッジサーバーID (参考情報) |
judge14 / judge12 |
| 純コード判定しない問題か言語 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 50 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
// #include <atcoder/all>
// using namespace atcoder;
#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#define rep(i,n) for(int i = 0; i < (n); ++i)
#define drep(i,n) for(int i = (n)-1; i >= 0; --i)
#define rng(a) a.begin(),a.end()
#define rrng(a) a.rbegin(),a.rend()
template<typename T> using vc = vector<T>;
template<typename T> using vv = vc<vc<T>>;
template<typename T> using PQ = priority_queue<T,vc<T>,greater<T> >;
template<typename T>void uni(T& a){sort(rng(a));a.erase(unique(rng(a)),a.end());}
using ll = long long;
using P = pair<int,int>;
int dx[4] = {-1,0,1,0};
int dy[4] = {0,-1,0,1};
constexpr int INF = 1001001001;
constexpr ll INFL = 1001002003004005006ll;
/*
mst で各放送局を連結にする
差分更新しない焼きなまし
近傍:放送局をひとつ選び出力を変更する
*/
inline unsigned long long xor128() {
static unsigned long long rx = 123456789, ry = 986960440, rz = 738905609, rw = 23140692;
unsigned long long rt = (rx ^ (rx << 11));
rx = ry;ry = rz;rz = rw;
return (rw = (rw ^ (rw >> 19)) ^ (rt ^ (rt >> 8)));
}
inline float rand128(float min = 0, float max = 1){
return (float)(xor128() % 0xFFFF) / 0xFFFF * (max - min) + min;
}
inline unsigned long long randint(int min, int max){
return xor128()%(max - min + 1) + min;
}
class TimeKeeper {
private:
std::chrono::high_resolution_clock::time_point start_time_;
int64_t time_threshold_;
public:
TimeKeeper(const int64_t& time_threshold)
: start_time_(std::chrono::high_resolution_clock::now()),
time_threshold_(time_threshold)
{}
bool isTimeOver() const {
using std::chrono::duration_cast;
using std::chrono::milliseconds;
auto diff = std::chrono::high_resolution_clock::now() - this->start_time_;
return duration_cast<milliseconds>(diff).count() >= time_threshold_;
}
};
// グローバル変数
int n; // 頂点数
vector<ll> ga;
vector<ll> gb;
void read_input() {
cin >> n;
ga.resize(n);
gb.resize(n);
rep(i,n) cin >> ga[i] >> gb[i];
}
struct Output {
int u,v;
Output (int u=0, int v=0) : u(u), v(v) {}
};
struct State {
vector<ll> a;
vector<ll> b;
vector<Output> ans;
State() {
a.resize(n);
b.resize(n);
a = ga;
b = gb;
}
void init() {
}
void make_init_ans() {
rep(i,50) {
int idx1 = randint(0,n-2);
int idx2 = randint(0,n-1);
if (idx1 == idx2) idx1++;
ans.push_back(Output(idx1,idx2));
ll va = (a[idx1]+a[idx2])/2;
ll vb = (b[idx1]+b[idx2])/2;
a[idx1] = a[idx2] = va;
b[idx1] = b[idx2] = vb;
}
}
void print_ans() {
cout << ans.size() << endl;
for (Output o : ans) {
cout << o.u << " " << o.v << endl;
}
}
void gready() {
set<P> st;
rep(i,10) {
int idx1 = randint(0,n-2);
int idx2 = randint(0,n-1);
if (idx1 == idx2) idx1++;
ans.push_back(Output(idx1+1,idx2+1));
ll va = (a[idx1]+a[idx2])/2;
ll vb = (b[idx1]+b[idx2])/2;
a[idx1] = a[idx2] = va;
b[idx1] = b[idx2] = vb;
}
rep(i,30) {
ll v1 = abs(5e17-a[0]);
ll v2 = abs(5e17-b[0]);
ll best_score = INFL;
int best_j = -1;
int best_k = -1;
for (int j=0; j<n; j++) {
for (int k=j+1; k<n; k++) {
ll va = (a[k]+a[j])/2;
ll vb = (b[k]+b[j])/2;
ll score = abs(va-vb);
if (st.count(P(j,k))) continue;
if (best_score > score) {
best_score = score;
best_j = j;
best_k = k;
}
}
}
if (best_j == -1) continue;
ans.push_back(Output(best_j+1,best_k+1));
ll va = (a[best_k]+a[best_j])/2;
ll vb = (b[best_k]+b[best_j])/2;
a[best_k] = a[best_j] = va;
b[best_k] = b[best_j] = vb;
st.insert(P(best_j,best_k));
}
rep(i,10) {
ll v1 = abs(5e17-a[0]);
ll v2 = abs(5e17-b[0]);
ll best_score = INFL;
int best_j = -1;
for (int j=1; j<n; j++) {
ll va = (a[0]+a[j])/2;
ll vb = (b[0]+b[j])/2;
ll vva = abs(5e17-va);
ll vvb = abs(5e17-vb);
ll score = max(vva,vvb);
if (best_score > score) {
best_score = score;
best_j = j;
}
}
if (best_j == -1) continue;
ans.push_back(Output(1,best_j+1));
ll va = (a[0]+a[best_j])/2;
ll vb = (b[0]+b[best_j])/2;
a[0] = a[best_j] = va;
b[0] = b[best_j] = vb;
}
}
ll calc_score() {
ll V1 = abs(a[0]-5e17);
ll V2 = abs(b[0]-5e17);
return 2000000 - 100000*log10(max(V1,V2)+1);
}
};
void simulatedAnnealing() {
TimeKeeper timer(900);
State state;
state.gready();
state.calc_score();
ll score = state.calc_score();
ll best_score = score;
double time_limit = 0.800;
double start_temp = 1000.0;
double end_temp = 10.0;
auto best_state = state;
int iter_count = 0;
while (!timer.isTimeOver()) {
iter_count++;
State next_state;
next_state.gready();
next_state.calc_score();
ll next_score = next_state.calc_score();
// score maximumize
// double temp = start_temp + (end_temp - start_temp) * timer.time() / time_limit;
// double probability = exp((next_score - now_score) / temp);
// bool is_force_next = probability > rand128();
// if (next_score > score || is_force_next) {
// if (next_score > score) {
// score = next_score;
// state = next_state;
// }
if (next_score > best_score) {
best_score = next_score;
best_state = state;
// cerr << "best score: " << best_score << endl;
}
}
best_state.print_ans();
cerr << "best_score:" << "\t" << best_score << endl;
cerr << "iter_count:" << "\t" << iter_count << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
read_input();
simulatedAnnealing();
return 0;
}