結果
問題 | No.5007 Steiner Space Travel |
ユーザー | hangry |
提出日時 | 2023-04-23 20:32:12 |
言語 | C++23 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 979 ms / 1,000 ms |
コード長 | 8,628 bytes |
コンパイル時間 | 4,648 ms |
コンパイル使用メモリ | 267,772 KB |
実行使用メモリ | 4,372 KB |
スコア | 7,592,088 |
最終ジャッジ日時 | 2023-04-23 20:32:51 |
合計ジャッジ時間 | 36,843 ms |
ジャッジサーバーID (参考情報) |
judge13 / judge11 |
純コード判定しない問題か言語 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 979 ms
4,368 KB |
testcase_01 | AC | 974 ms
4,368 KB |
testcase_02 | AC | 974 ms
4,368 KB |
testcase_03 | AC | 974 ms
4,372 KB |
testcase_04 | AC | 977 ms
4,368 KB |
testcase_05 | AC | 975 ms
4,372 KB |
testcase_06 | AC | 974 ms
4,368 KB |
testcase_07 | AC | 976 ms
4,368 KB |
testcase_08 | AC | 975 ms
4,368 KB |
testcase_09 | AC | 973 ms
4,372 KB |
testcase_10 | AC | 974 ms
4,368 KB |
testcase_11 | AC | 977 ms
4,372 KB |
testcase_12 | AC | 975 ms
4,372 KB |
testcase_13 | AC | 976 ms
4,368 KB |
testcase_14 | AC | 975 ms
4,372 KB |
testcase_15 | AC | 974 ms
4,372 KB |
testcase_16 | AC | 974 ms
4,372 KB |
testcase_17 | AC | 977 ms
4,372 KB |
testcase_18 | AC | 979 ms
4,372 KB |
testcase_19 | AC | 974 ms
4,368 KB |
testcase_20 | AC | 974 ms
4,368 KB |
testcase_21 | AC | 973 ms
4,368 KB |
testcase_22 | AC | 974 ms
4,372 KB |
testcase_23 | AC | 977 ms
4,368 KB |
testcase_24 | AC | 977 ms
4,372 KB |
testcase_25 | AC | 978 ms
4,368 KB |
testcase_26 | AC | 977 ms
4,368 KB |
testcase_27 | AC | 975 ms
4,368 KB |
testcase_28 | AC | 974 ms
4,368 KB |
testcase_29 | AC | 976 ms
4,368 KB |
ソースコード
#include <bits/stdc++.h> //#include <atcoder> using namespace std; //using namespace atcoder; #define rep(i, n) for (int i = 0; i < (int)(n); i++) #define repab(i, a, b) for (int i = (int)(a); i <= (int)(b); i++) #define repabc(i, a, b, c) for (int i = (int)(a); i <= (int)(b); i += c) #define rrep(i, n) for (int i = (int)(n)-1; i >= 0; i--) #define rrepab(i, a, b) for (int i = (int)(b); i >= (int)(a); i--) #define rrepabc(i, a, b, c) for (int i = (int)(b); i >= (int)(a); i-=c) #define printl(...) cerr << "LINE=" << __LINE__ << " "; print(__VA_ARGS__) void in_print() {} template <class Head, class... Tail> void in_print(Head&& head, Tail&&... tail) { cerr << "," << head; in_print(forward<Tail>(tail)...); } void print() {} template <class Head, class... Tail> void print(Head&& head, Tail&&... tail) { cerr << head; in_print(forward<Tail>(tail)...); cerr << endl; } unsigned int randxor() { static unsigned int x=123456789,y=362436069,z=521288629,w=88675123; unsigned int t; t=(x^(x<<11));x=y;y=z;z=w; return( w=(w^(w>>19))^(t^(t>>8)) ); } //char grid[8][8]; //static const int dx[] = {0,-1,0,1,1,-1,-1,1}; //static const int dy[] = {-1,0,1,0,1,1,-1,-1}; //static const char dir[] = {'L','U','R','D'}; auto start_time = chrono::system_clock::now(); auto end_time = chrono::system_clock::now(); //if (chrono::duration_cast<chrono::milliseconds>(end_time - start_time).count() > 500) int N = 100; int M = 8; int planet[100][2]; int station[8][2]; int alpha = 5; typedef vector<int> vi; typedef vector<vector<int>> vvi; void load_data() { cin >> N >> M; rep(i, N) rep(j, 2) cin >> planet[i][j]; rep(i, 8) rep(j, 2) station[i][j] = i*100; } double calc_score(vvi &st, vvi &ans) { long long energy = 0; int x = planet[0][0]; int y = planet[0][1]; int nowt = 1; rep(i, (int)ans.size()) { if (ans[i][0] == 1) { if (nowt == 1) energy += 25 * ((x-planet[ans[i][1]][0])*(x-planet[ans[i][1]][0]) + (y-planet[ans[i][1]][1])*(y-planet[ans[i][1]][1])); else energy += 5 * ((x-planet[ans[i][1]][0])*(x-planet[ans[i][1]][0]) + (y-planet[ans[i][1]][1])*(y-planet[ans[i][1]][1])); x = planet[ans[i][1]][0]; y = planet[ans[i][1]][1]; } else { if (nowt == 2) energy += ((x-st[ans[i][1]][0])*(x-st[ans[i][1]][0]) + (y-st[ans[i][1]][1])*(y-st[ans[i][1]][1])); else energy += 5 * ((x-st[ans[i][1]][0])*(x-st[ans[i][1]][0]) + (y-st[ans[i][1]][1])*(y-st[ans[i][1]][1])); x = st[ans[i][1]][0]; y = st[ans[i][1]][1]; } nowt = ans[i][0]; } return round(1000000000.0/(1000.0 + sqrt(energy))); } void make_first_ans(vvi &fans) { vi dd = {1, 0}; fans.push_back(dd); repab(i, 1, N-1) { vi dd = {1, i}; fans.push_back(dd); } vi dc = {1, 0}; fans.push_back(dc); } void print_ans(vvi &st, vvi &ans) { rep(i, 8) cout << st[i][0] << " " << st[i][1] << endl; cout << ans.size() << endl; rep(i, (int)ans.size()) cout << ans[i][0] << " " << ans[i][1]+1 << endl; } struct STATE { double score; vvi robo; vvi move; vi cnt; }; void simulated_annealing() { double start_tmp = 205; double end_tmp = 1; int sa_end_time = 970; double fsc = 0.0; vvi frobo; rep(i, 8) frobo.push_back({station[i][0], station[i][1]}); vvi fmove; make_first_ans(fmove); vi fcnt; rep(i, N) { if (i == 0) fcnt.push_back(2); else fcnt.push_back(1); } STATE state = {fsc, frobo, fmove, fcnt}; int cnt = 0; while (true) { if (cnt % 1000 == 0) { end_time = chrono::system_clock::now(); if (chrono::duration_cast<chrono::milliseconds>(end_time - start_time).count() > sa_end_time) break; } cnt += 1; //STATE nxt = state; int opt = randxor() % 6; //int opt = 3; if (opt == 0) { int posi = randxor() % 8; vvi robo = state.robo; robo[posi][0] += -min(50, robo[posi][0]) + (randxor() % max(1, min(50, robo[posi][0])+min(50, 1000-robo[posi][0]))); robo[posi][1] += -min(50, robo[posi][1]) + (randxor() % max(1, min(50, robo[posi][1])+min(50, 1000-robo[posi][1]))); double nextscore = calc_score(robo, state.move); //nxt.score = nextscore; double nowscore = state.score; double temp = start_tmp + (end_tmp - start_tmp) * (chrono::duration_cast<chrono::milliseconds>(end_time - start_time).count()) / sa_end_time; double prob = exp((nextscore - nowscore)/temp); if (prob > (randxor() % 10000)/10000.0) { state.robo = robo; state.score = nextscore; } } else if (opt == 1) { vvi nxt = state.move; int posi = 1 + randxor() % (max(1, (int)state.move.size()-2)); int tp = randxor() % 10; int ad; if (tp < 3) { ad = randxor() % 8; nxt.insert(nxt.begin() + posi, {2, ad}); } else { ad = randxor() % 100; nxt.insert(nxt.begin() + posi, {1, ad}); //kkkkkkkkkkkkkkkkkkkknxt.cnt[ad] += 1; } double nextscore = calc_score(state.robo, nxt); //nxt.score = nextscore; double nowscore = state.score; double temp = start_tmp + (end_tmp - start_tmp) * (chrono::duration_cast<chrono::milliseconds>(end_time - start_time).count()) / sa_end_time; double prob = exp((nextscore - nowscore)/temp); if (prob > (randxor() % 10000)/10000.0) { state.move = nxt; if (tp >= 3) state.cnt[ad] += 1; state.score = nextscore; } } else if ( opt == 2) { vvi nxt = state.move; int posi = 1 + (randxor() % (max(1, (int)state.move.size() - 2))); if (state.move[posi][0] == 1) { if (state.cnt[state.move[posi][1]] > 1) { //kkkkkkkkkkkkkkkkkkkkkkkkkknxt.cnt[nxt.move[posi][1]] -= 1; nxt.erase(nxt.begin() + posi); } else continue; } else nxt.erase(nxt.begin() + posi); double nextscore = calc_score(state.robo, nxt); //nxt.score = nextscore; double nowscore = state.score; double temp = start_tmp + (end_tmp - start_tmp) * (chrono::duration_cast<chrono::milliseconds>(end_time - start_time).count()) / sa_end_time; double prob = exp((nextscore - nowscore)/temp); if (prob > (randxor() % 10000)/10000.0) { if (state.move[posi][0] == 1) state.cnt[state.move[posi][1]] -= 1; state.move = nxt; state.score = nextscore; } } else if (opt == 3) { int posi = 1 + (randxor() % max(1, (int)state.move.size() - 3)); swap(state.move[posi], state.move[posi+1]); double nextscore = calc_score(state.robo, state.move); //nxt.score = nextscore; double nowscore = state.score; double temp = start_tmp + (end_tmp - start_tmp) * (chrono::duration_cast<chrono::milliseconds>(end_time - start_time).count()) / sa_end_time; double prob = exp((nextscore - nowscore)/temp); if (prob > (randxor() % 10000)/10000.0) { state.score = nextscore; } else { swap(state.move[posi], state.move[posi+1]); } } else if (opt == 4) { int p1 = 1 + (randxor() % max(1, (int)state.move.size() - 2)); int p2 = 1 + (randxor() % max(1, (int)state.move.size() - 2)); swap(state.move[p1], state.move[p2]); double nextscore = calc_score(state.robo, state.move); //nxt.score = nextscore; double nowscore = state.score; double temp = start_tmp + (end_tmp - start_tmp) * (chrono::duration_cast<chrono::milliseconds>(end_time - start_time).count()) / sa_end_time; double prob = exp((nextscore - nowscore)/temp); if (prob > (randxor() % 10000)/10000.0) { state.score = nextscore; } else { swap(state.move[p1], state.move[p2]); } } else if (opt == 5) { STATE nxt = state; int posi = 1 + (randxor() % (max(1, (int)state.move.size() - 2))); vi tmp = nxt.move[posi]; nxt.move.erase(nxt.move.begin() + posi); int ad = 1 + (randxor() % (max(1, (int)state.move.size() - 2))); nxt.move.insert(nxt.move.begin() + ad, tmp); double nextscore = calc_score(nxt.robo, nxt.move); nxt.score = nextscore; double nowscore = state.score; double temp = start_tmp + (end_tmp - start_tmp) * (chrono::duration_cast<chrono::milliseconds>(end_time - start_time).count()) / sa_end_time; double prob = exp((nextscore - nowscore)/temp); if (prob > (randxor() % 10000)/10000.0) { state = nxt; } } } print("cnt=", cnt); print(state.score); print_ans(state.robo, state.move); } int main() { load_data(); simulated_annealing(); }