結果

問題 No.5017 Tool-assisted Shooting
ユーザー wanui
提出日時 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
権限があれば一括ダウンロードができます

ソースコード

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

#include <bits/stdc++.h>
// clang-format off
using 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 on
namespace 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 marathon
const 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;
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0