結果
| 問題 | No.5017 Tool-assisted Shooting |
| コンテスト | |
| ユーザー |
tishii24
|
| 提出日時 | 2023-08-03 23:31:40 |
| 言語 | Rust (1.83.0 + proconio) |
| 結果 |
RE
|
| 実行時間 | - |
| コード長 | 6,682 bytes |
| コンパイル時間 | 2,323 ms |
| コンパイル使用メモリ | 153,248 KB |
| 実行使用メモリ | 36,032 KB |
| スコア | 77 |
| 平均クエリ数 | 0.01 |
| 最終ジャッジ日時 | 2023-08-03 23:31:53 |
| 合計ジャッジ時間 | 7,381 ms |
|
ジャッジサーバーID (参考情報) |
judge15 / judge13 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | RE * 1 TLE * 1 -- * 98 |
コンパイルメッセージ
warning: field `initial_h` is never read
--> Main.rs:115:5
|
114 | struct Enemy {
| ----- field in this struct
115 | initial_h: i64,
| ^^^^^^^^^
|
= note: `Enemy` has derived impls for the traits `Debug` and `Clone`, but these are intentionally ignored during dead code analysis
= note: `#[warn(dead_code)]` on by default
warning: 1 warning emitted
ソースコード
pub mod util {
#[allow(unused_features)]
pub mod rnd {
#[allow(unused)]
static mut S: usize = 88172645463325252;
#[allow(unused)]
#[inline]
pub fn next() -> usize {
unsafe {
S = S ^ S << 7;
S = S ^ S >> 9;
S
}
}
#[allow(unused)]
#[inline]
pub fn nextf() -> f64 {
(next() & 4294967295) as f64 / 4294967296.
}
#[allow(unused)]
#[inline]
pub fn gen_range(low: usize, high: usize) -> usize {
(next() % (high - low)) + low
}
#[allow(unused)]
pub fn shuffle<I>(vec: &mut Vec<I>) {
for i in 0..vec.len() {
let j = gen_range(0, vec.len());
vec.swap(i, j);
}
}
}
pub mod time {
static mut START: f64 = -1.;
#[allow(unused)]
pub fn start_clock() {
let _ = elapsed_seconds();
}
#[allow(unused)]
#[inline]
pub fn elapsed_seconds() -> f64 {
let t = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_secs_f64();
unsafe {
if START < 0. {
START = t;
}
t - START
}
}
}
}
use std::io::{stdout, Write};
use crate::util::*;
macro_rules! get {
($t:ty) => {
{
let mut line: String = String::new();
std::io::stdin().read_line(&mut line).unwrap();
line.trim().parse::<$t>().unwrap()
}
};
($($t:ty),*) => {
{
let mut line: String = String::new();
std::io::stdin().read_line(&mut line).unwrap();
let mut iter = line.split_whitespace();
(
$(iter.next().unwrap().parse::<$t>().unwrap(),)*
)
}
};
($t:ty; $n:expr) => {
(0..$n).map(|_|
get!($t)
).collect::<Vec<_>>()
};
($($t:ty),*; $n:expr) => {
(0..$n).map(|_|
get!($($t),*)
).collect::<Vec<_>>()
};
($t:ty ;;) => {
{
let mut line: String = String::new();
std::io::stdin().read_line(&mut line).unwrap();
line.split_whitespace()
.map(|t| t.parse::<$t>().unwrap())
.collect::<Vec<_>>()
}
};
($t:ty ;; $n:expr) => {
(0..$n).map(|_| get!($t ;;)).collect::<Vec<_>>()
};
}
const H: usize = 60;
const W: usize = 25;
const T: usize = 1000;
#[derive(Clone, Default, Debug)]
struct Enemy {
initial_h: i64,
current_h: i64,
p: i64,
}
fn dist(x1: usize, x2: usize) -> i64 {
let xl = usize::min(x1, x2) as i64;
let xr = usize::max(x1, x2) as i64;
return i64::min(xr - xl, xl + W as i64 - xr);
}
#[derive(PartialEq, Eq)]
enum Move {
Stay,
Left,
Right,
}
struct State {
s: i64,
cx: usize,
}
impl State {
fn perform(&mut self, m: &Move) {
match m {
Move::Stay => println!("S"),
Move::Left => {
println!("L");
self.cx = left_x(self.cx);
}
Move::Right => {
println!("R");
self.cx = right_x(self.cx);
}
};
stdout().flush().unwrap();
}
}
fn nearest_e_y(field: &Vec<Vec<Option<Enemy>>>, x: usize, t: usize) -> Option<usize> {
for y in t + 1..t + H {
if field[y][x].is_some() {
return Some(y);
}
}
None
}
fn left_x(cx: usize) -> usize {
if cx == 0 {
W - 1
} else {
cx - 1
}
}
fn right_x(cx: usize) -> usize {
if cx == W - 1 {
0
} else {
cx + 1
}
}
fn is_ok(field: &Vec<Vec<Option<Enemy>>>, t: usize, x: usize) -> bool {
field[t][x].is_none() && field[t + 1][x].is_none()
}
fn move_to_x(cx: usize, to_x: usize) -> Move {
if to_x == cx {
Move::Stay
} else if to_x < cx {
if cx - to_x <= W / 2 {
Move::Left
} else {
Move::Right
}
} else {
if to_x - cx <= W / 2 {
Move::Right
} else {
Move::Left
}
}
}
fn check_move(m: Move, field: &Vec<Vec<Option<Enemy>>>, t: usize, cx: usize) -> Move {
let mut m = m;
let nx = match m {
Move::Stay => cx,
Move::Left => left_x(cx),
Move::Right => right_x(cx),
};
if !is_ok(field, t, nx) {
m = if m == Move::Stay {
Move::Left
} else {
Move::Stay
};
}
m
}
fn attack(state: &mut State, field: &mut Vec<Vec<Option<Enemy>>>, t: usize) {
if let Some(y) = nearest_e_y(&field, state.cx, t) {
let e = field[y][state.cx].as_mut().unwrap();
e.current_h -= state.s / 100 + 1;
if e.current_h <= 0 {
// eprintln!("destroy: p={}, h={}, x={}", e.p, e.initial_h, state.cx);
state.s += e.p;
field[y][state.cx] = None;
}
}
}
fn main() {
time::start_clock();
let mut field = vec![vec![None; W as usize]; (2 * H + T) as usize];
std::io::stdin().read_line(&mut String::new()).unwrap();
let mut state = State { s: 0, cx: 12 };
for t in 0..T {
// if field[t][state.cx].is_some() { eprintln!("xxx {} {}", t, state.cx); break; }
let n = get!(i64);
if n == -1 {
break;
}
for _ in 0..n {
let (h, p, x) = get!(i64, i64, i64);
field[t + H - 1][x as usize] = Some(Enemy {
initial_h: h,
current_h: h,
p,
});
}
let mut best_x = 0;
let mut best_eval = 0.;
for x in 0..W {
if let Some(y) = nearest_e_y(&field, x, t) {
let e = field[y][x].as_ref().unwrap();
let turn = e.current_h / (state.s / 100 + 1) + i64::max(0, dist(x, state.cx));
if turn >= (y - t) as i64 {
break;
}
let eval = e.p as f64 / turn as f64;
if eval > best_eval {
best_eval = eval;
best_x = x;
}
}
}
let m = move_to_x(state.cx, best_x);
let m = check_move(m, &field, t, state.cx);
state.perform(&m);
// if field[t][state.cx].is_some() { eprintln!("xxx {} {}", t, state.cx); break; }
attack(&mut state, &mut field, t);
}
}
tishii24