結果
問題 | No.5016 Worst Mayor |
ユーザー |
![]() |
提出日時 | 2023-04-29 16:59:55 |
言語 | C++17(gcc12) (gcc 12.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 220 ms / 2,000 ms |
コード長 | 8,991 bytes |
コンパイル時間 | 2,567 ms |
コンパイル使用メモリ | 138,764 KB |
実行使用メモリ | 24,492 KB |
スコア | 5,664,711,582 |
平均クエリ数 | 400.00 |
最終ジャッジ日時 | 2023-04-29 17:03:39 |
合計ジャッジ時間 | 15,652 ms |
ジャッジサーバーID (参考情報) |
judge15 / judge16 |
純コード判定しない問題か言語 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 50 |
ソースコード
#include <iostream>#include <vector>#include <queue>#include <string>#include <sstream>#include <algorithm>#include <random>#include <cassert>#include <math.h>#define rep(i,n) for(int i = 0; i < (int)(n); i++)using namespace std;using LL = long long;using pii = pair<int,int>;const int INF = (int)1e9;const LL LINF = (LL)1e18;const int grid_size = 14;const int max_turn = 400;const int testcase = 0;const int dy[4] = {0, 0, 1, -1};const int dx[4] = {1, -1, 0, 0};enum class file_status{local,debug,submit,};file_status now_status = file_status::submit;void read_input(){std::stringstream ss;std::string num = std::to_string(testcase);int siz = num.size();for(int i = 0; i < 4 - siz; i++) num = '0' + num;ss << "in/" << num << ".txt";FILE *in = freopen(ss.str().c_str(), "r", stdin);}void file_output(){std::stringstream ss;std::string num = std::to_string(testcase);int siz = num.size();for(int i = 0; i < 4 - siz; i++) num = '0' + num;ss << "out/" << num << ".txt";FILE *out = freopen(ss.str().c_str(), "w", stdout);}random_device rnd;mt19937 engine(rnd());bool range_out(int y, int x){if(y < 0 || y >= grid_size) return true;if(x < 0 || x >= grid_size) return true;return false;}// 入力の受け取りint N, T;vector<pii> S, G;// 各道路の評価 (0 - 181 が東西、182 - 363 が南北)double roads[13*14*2];vector<pii> road_eval;struct road_pos{int a, b, c, d;road_pos(int a, int b, int c, int d) :a(a), b(b), c(c), d(d) {}};road_pos convert(int road_num){// 東西の道路if(road_num < 13 * 14){int y = road_num / 13, x = road_num % 13;int a = y + 1, c = y + 1;int b = x + 1, d = x + 2;return road_pos(a, b, c, d);}// 南北の道路else{road_num -= 13 * 14;int y = road_num % 13, x = road_num / 13;int a = y + 1, c = y + 2;int b = x + 1, d = x + 1;return road_pos(a, b, c, d);}}int calc_road_num(int y, int x, int k){// 東西の道路if(k == 0){ // 東へreturn y * 13 + x;}else if(k == 1){ // 西へreturn y * 13 + x - 1;}// 南北の道路else if(k == 2){ // 南へreturn 13 * 14 + x * 13 + y;}else{ // 北へreturn 13 * 14 + x * 13 + y - 1;}}struct path{int y, x;int highway;int dist;path(int y, int x, int h, int d) :y(y), x(x), highway(h), dist(d) {}bool operator> (const path& p) const{return dist > p.dist;}};LL CalcProfit(vector<int>& highway){LL res = 0;rep(i,N){priority_queue<path,vector<path>,greater<>> pq;vector dist = vector(grid_size, vector<int>(grid_size, INF));pq.emplace(S[i].first, S[i].second, 0, 0);dist[S[i].first][S[i].second] = 0;while(!pq.empty()){path p = pq.top(); pq.pop();if(p.y == G[i].first && p.x == G[i].second){res += 60 * p.highway;break;}if(p.dist != dist[p.y][p.x]) continue;rep(k,4){int ny = p.y + dy[k], nx = p.x + dx[k];if(range_out(ny, nx)) continue;int nd = p.dist;int road_num = calc_road_num(p.y, p.x, k);int cost = 1000;if(highway[road_num]){cost = 223;}nd += cost;if(nd >= dist[ny][nx]) continue;dist[ny][nx] = nd;if(highway[road_num]){pq.emplace(ny, nx, p.highway + 1, nd);}else{pq.emplace(ny, nx, p.highway, nd);}}}}return res;}LL CalcScore(vector<pii>& actions){assert((int)actions.size() == T);LL res = (int)1e6;int staff = 1;vector<int> highway(13*14*2);for(auto& action : actions){int kind = action.first;if(kind == 1){int cost = 1e7 / sqrt((double)staff);assert(cost <= res);res -= cost;highway[action.second] = 1;}else if(kind == 2){staff++;}else{res += 50000;}/*LL profit = CalcProfit(highway);if(now_status == file_status::debug){cout << "profit = " << profit << endl;}res += profit;*/}return res;}void calc_roads(){rep(i,N){int a = S[i].first, b = S[i].second;int c = G[i].first, d = G[i].second;if(a > c) swap(a, c);if(b > d) swap(b, d);double y_mid = (double)(a + c) / 2;double x_mid = (double)(b + d) / 2;double yl = (double)a - y_mid, yr = (double)c - y_mid;double xl = (double)b - x_mid, xr = (double)d - x_mid;// 東西の道路for(int y = a; y <= c; y++){for(int x = b; x < d; x++){int num = 13 * y + x;roads[num] += 20.0;}}// 南北の道路for(int x = b; x <= d; x++){for(int y = a; y < c; y++){int num = 13 * 14 + 13 * x + y;roads[num] += 20.0;}}}for(int i = 0; i < 13 * 14 * 2; i++){road_eval.emplace_back((int)roads[i], i);}sort(road_eval.begin(), road_eval.end(), greater<>());}struct node{int turn;LL cash;int staff, highway;LL eval;LL profit;vector<pii> actions;node(){turn = 0;cash = (int)1e6;staff = 1;highway = 0;eval = cash;profit = 0;}bool construction(){if(highway >= 13 * 14 * 2) return false;int cost = 1e7 / sqrt((double)staff);if(cost > cash) return false;cash -= cost; eval -= cost;eval += (max_turn - turn) * road_eval[highway].first;actions.emplace_back(1, road_eval[highway].second);// 収益を更新する/*vector<int> constructed_highway(13*14*2);for(int i = 0; i <= highway; i++){constructed_highway[road_eval[i].second] = 1;}profit = CalcProfit(constructed_highway);*/profit += road_eval[highway].first;highway++;return true;}void gather_staff(){staff++;actions.emplace_back(2, -1);}void funding(){cash += 50000; eval += 50000;actions.emplace_back(3, -1);}void update(){turn++;cash += profit;}bool operator< (const node &v) const{return eval < v.eval;}};node BeamSearch(){priority_queue<node> pq;const int beam_width = 100;pq.emplace();rep(t,T){priority_queue<node> next_pq;rep(i,beam_width){if(pq.empty()) break;node v = pq.top(); pq.pop();// 高速道路の建設node v1 = v;if(v1.construction()){v1.update();next_pq.emplace(v1);}// 協力者の招集node v2 = v;v2.gather_staff();v2.update();next_pq.emplace(v2);// 資金調達if(v.turn > 100){node v3 = v;v3.funding();v3.update();next_pq.emplace(v3);}}pq = next_pq;}node best_node;int best_score = 0;while(!pq.empty()){node v = pq.top(); pq.pop();if(v.cash > best_score){best_node = v;best_score = v.cash;}}return best_node;}int main(){if(now_status != file_status::submit){read_input();file_output();}cin >> N >> T;rep(i,N){int a, b, c, d;cin >> a >> b >> c >> d;a--; b--; c--; d--;S.emplace_back(a, b);G.emplace_back(c, d);}calc_roads();if(now_status == file_status::debug){for(auto& val : road_eval){cout << val.first << " " << val.second << endl;}}node best_node = BeamSearch();vector<pii> ans = best_node.actions;rep(i,T){if(now_status == file_status::submit){int u, v;cin >> u >> v;}int kind = ans[i].first;if(kind == 1){int num = ans[i].second;road_pos p = convert(num);cout << kind << " " << p.a << " " << p.b<< " " << p.c << " " << p.d << endl;}else cout << kind << endl;}if(now_status != file_status::submit){cerr << "score = " << CalcScore(ans) << endl;}return 0;}