結果
問題 | No.5017 Tool-assisted Shooting |
ユーザー |
|
提出日時 | 2023-07-16 16:27:10 |
言語 | C++17(gcc12) (gcc 12.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 93 ms / 2,000 ms |
コード長 | 6,112 bytes |
コンパイル時間 | 2,461 ms |
コンパイル使用メモリ | 206,632 KB |
実行使用メモリ | 24,408 KB |
スコア | 3,633,838 |
平均クエリ数 | 932.97 |
最終ジャッジ日時 | 2023-07-16 16:28:03 |
合計ジャッジ時間 | 14,209 ms |
ジャッジサーバーID (参考情報) |
judge15 / judge14 |
純コード判定しない問題か言語 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 100 |
ソースコード
#include <bits/stdc++.h>// clang-format offusing namespace std; using ll=long long; using ull=unsigned long long; using pll=pair<ll,ll>; const ll INF=4e18;#define debug1(a) { cerr<<#a<<":"<<a<<endl; }#define debug2(a,b) { cerr<<#a<<":"<<a<<" "<<#b<<":"<<b<<endl; }#define debug3(a,b,c) { cerr<<#a<<":"<<a<<" "<<#b<<":"<<b<<" "<<#c<<":"<<c<<endl; }#define debug4(a,b,c,d) { cerr<<#a<<":"<<a<<" "<<#b<<":"<<b<<" "<<#c<<":"<<c<<" "<<#d<<":"<<d<<endl; }struct point {int r; int c; };bool operator==(const point &lhs, const point &rhs) { return (lhs.r == rhs.r && lhs.c == rhs.c); }bool operator!=(const point &lhs, const point &rhs) { return !(lhs == rhs); }bool operator<(const point &lhs, const point &rhs) {if (lhs.r != rhs.r){return lhs.r<rhs.r;}return lhs.c<rhs.c;}point operator-(const point &self){return {-self.r, -self.c};}point operator+(const point &lhs, const point &rhs){return {lhs.r+rhs.r, lhs.c+rhs.c};}point operator-(const point &lhs, const point &rhs){return lhs + (-rhs);}std::ostream &operator<<(std::ostream &os, point &pt) {string s;s = "(" + to_string(int(pt.r)) + ", " + to_string(int(pt.c)) + ")";return os << s;};// clang-format onnamespace marathon {mt19937 engine(0);clock_t start_time;double now() {return 1000.0 * (clock() - start_time) / CLOCKS_PER_SEC;}void marathon_init() {start_time = clock();random_device seed_gen;engine.seed(seed_gen());}int randint(int mn, int mx) {int rng = mx - mn + 1;return mn + (engine() % rng);}double uniform(double x, double y) {const int RND = 1e8;double mean = (x + y) / 2.0;double dif = y - mean;double p = double(engine() % RND) / RND;return mean + dif * (1.0 - 2.0 * p);}} // namespace marathonconst int INIT_MY_C = 12;const int H = 60;const int W = 25;struct enemy_t {int init_hp;int hp;int power;};struct state_t {enemy_t board[H][W];int total_power;int total_hp;int my_c;int turn;int level() {return 1 + total_power / 100;}};void read_enemies(state_t &state) {int n;cin >> n;for (int it = 0; it < n; it++) {int h, p, x;cin >> h >> p >> x;enemy_t e;e.hp = h;e.init_hp = h;e.power = p;state.board[H - 1][x] = e;}}bool move_enemies(state_t &state) {for (int r = 0; r < H - 1; r++) {for (int c = 0; c < W; c++) {state.board[r][c] = state.board[r + 1][c];}}for (int c = 0; c < W; c++) {state.board[H - 1][c] = {-1, -1, -1};}return state.board[0][state.my_c].hp <= 0;}char select_op(state_t &state) {int turn = state.turn;vector<double> scores(3, 0.0);for (int pi = 0; pi <= 2; pi++) {scores[pi] = marathon::uniform(0.01, 0.02);int c = state.my_c;if (pi == 0) {c--;} else if (pi == 2) {c++;}// 盤面の外if (c < 0 || c >= W) {scores[pi] += -1e18;continue;}// ゲームオーバーif (state.board[0][c].hp > 0) {scores[pi] += -1e16;}// 敵への攻撃for (int r = 1; r < H; r++) {int level = state.level();enemy_t e = state.board[r][c];if (e.hp <= 0) continue;int turns = (e.hp + level - 1) / level;if (turns > r) scores[pi] += -1e10; // 倒せるかどうかdouble ratio = 1.0 * e.power / turns;scores[pi] += ratio * 1e5;break;}// 敵との近さfor (int d = 0; d < W; d++) {for (int r = 1; r < H; r++) {int distance = abs(c - d);enemy_t e = state.board[r][d];if (e.hp <= 0) continue;int level = state.level(); // 本当は途中でレベルが上がるが...int turns = (e.hp + level - 1) / level;if (turns + abs(c - d) > r) continue; // 倒せるかどうかdouble ratio = 1.0 * e.power / turns;scores[pi] += ratio / (distance + 1.0); // TODO 適当}}}pair<double, int> max_score = {-1e50, -1};for (int i = 0; i <= 2; i++) {max_score = max({scores[i], i}, max_score);}if (max_score.second == 0) {return 'L';} else if (max_score.second == 2) {return 'R';} else {return 'S';}}bool move_attack(state_t &state, char op) {if (op == 'L') {state.my_c--;} else if (op == 'R') {state.my_c++;}if (state.board[0][state.my_c].hp > 0) return false;for (int i = 1; i < H; i++) {if (state.board[i][state.my_c].hp > 0) {state.board[i][state.my_c].hp -= state.level();// debug4(state.turn, i, state.my_c, state.level());if (state.board[i][state.my_c].hp <= 0) {state.total_power += state.board[i][state.my_c].power;state.total_hp += state.board[i][state.my_c].init_hp;state.board[i][state.my_c] = {-1, -1, -1};}break;}}return true;}int main() {marathon::marathon_init();state_t state;{state.total_power = 0;state.total_hp = 0;state.my_c = INIT_MY_C;for (int r = 0; r < H; r++) {for (int c = 0; c < W; c++) {state.board[r][c] = {-1, -1, -1};}}}for (int turn = 1; turn <= 1000; turn++) {state.turn = turn;bool alive1 = move_enemies(state);if (!alive1) break;read_enemies(state);char op = select_op(state);cout << op << endl;bool alive2 = move_attack(state, op);if (!alive2) break;}cerr << "score==" << state.total_hp << " turn==" << state.turn << " power==" << state.total_power << " time==" << marathon::now() << endl;return 0;}