結果
問題 | No.5017 Tool-assisted Shooting |
ユーザー | shamio |
提出日時 | 2023-07-16 18:04:07 |
言語 | Rust (1.77.0 + proconio) |
結果 |
AC
|
実行時間 | 108 ms / 2,000 ms |
コード長 | 10,824 bytes |
コンパイル時間 | 5,601 ms |
コンパイル使用メモリ | 211,144 KB |
実行使用メモリ | 24,372 KB |
スコア | 3,487,022 |
平均クエリ数 | 967.02 |
最終ジャッジ日時 | 2023-07-16 18:04:28 |
合計ジャッジ時間 | 19,916 ms |
ジャッジサーバーID (参考情報) |
judge14 / judge12 |
純コード判定しない問題か言語 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 101 ms
23,952 KB |
testcase_01 | AC | 97 ms
23,808 KB |
testcase_02 | AC | 97 ms
23,388 KB |
testcase_03 | AC | 98 ms
23,388 KB |
testcase_04 | AC | 97 ms
23,472 KB |
testcase_05 | AC | 99 ms
23,988 KB |
testcase_06 | AC | 97 ms
23,844 KB |
testcase_07 | AC | 96 ms
23,640 KB |
testcase_08 | AC | 98 ms
23,844 KB |
testcase_09 | AC | 84 ms
23,604 KB |
testcase_10 | AC | 95 ms
23,400 KB |
testcase_11 | AC | 71 ms
24,312 KB |
testcase_12 | AC | 92 ms
23,580 KB |
testcase_13 | AC | 97 ms
23,964 KB |
testcase_14 | AC | 100 ms
24,180 KB |
testcase_15 | AC | 98 ms
24,276 KB |
testcase_16 | AC | 95 ms
23,472 KB |
testcase_17 | AC | 99 ms
24,036 KB |
testcase_18 | AC | 98 ms
23,376 KB |
testcase_19 | AC | 94 ms
24,276 KB |
testcase_20 | AC | 95 ms
23,664 KB |
testcase_21 | AC | 97 ms
23,532 KB |
testcase_22 | AC | 94 ms
23,592 KB |
testcase_23 | AC | 98 ms
23,532 KB |
testcase_24 | AC | 97 ms
23,832 KB |
testcase_25 | AC | 99 ms
24,348 KB |
testcase_26 | AC | 91 ms
23,976 KB |
testcase_27 | AC | 89 ms
23,592 KB |
testcase_28 | AC | 99 ms
23,484 KB |
testcase_29 | AC | 97 ms
23,472 KB |
testcase_30 | AC | 96 ms
24,348 KB |
testcase_31 | AC | 97 ms
23,484 KB |
testcase_32 | AC | 93 ms
24,024 KB |
testcase_33 | AC | 103 ms
24,036 KB |
testcase_34 | AC | 97 ms
23,316 KB |
testcase_35 | AC | 97 ms
23,448 KB |
testcase_36 | AC | 97 ms
23,316 KB |
testcase_37 | AC | 99 ms
24,276 KB |
testcase_38 | AC | 97 ms
23,388 KB |
testcase_39 | AC | 97 ms
24,036 KB |
testcase_40 | AC | 98 ms
24,288 KB |
testcase_41 | AC | 84 ms
23,964 KB |
testcase_42 | AC | 99 ms
24,288 KB |
testcase_43 | AC | 90 ms
24,024 KB |
testcase_44 | AC | 97 ms
23,412 KB |
testcase_45 | AC | 79 ms
23,364 KB |
testcase_46 | AC | 94 ms
23,664 KB |
testcase_47 | AC | 92 ms
23,820 KB |
testcase_48 | AC | 87 ms
24,288 KB |
testcase_49 | AC | 95 ms
23,940 KB |
testcase_50 | AC | 96 ms
23,640 KB |
testcase_51 | AC | 92 ms
23,664 KB |
testcase_52 | AC | 95 ms
23,652 KB |
testcase_53 | AC | 96 ms
23,340 KB |
testcase_54 | AC | 69 ms
23,472 KB |
testcase_55 | AC | 94 ms
23,376 KB |
testcase_56 | AC | 96 ms
23,592 KB |
testcase_57 | AC | 85 ms
24,216 KB |
testcase_58 | AC | 96 ms
23,568 KB |
testcase_59 | AC | 88 ms
23,436 KB |
testcase_60 | AC | 92 ms
24,312 KB |
testcase_61 | AC | 99 ms
23,472 KB |
testcase_62 | AC | 98 ms
23,544 KB |
testcase_63 | AC | 97 ms
23,976 KB |
testcase_64 | AC | 97 ms
24,336 KB |
testcase_65 | AC | 97 ms
23,664 KB |
testcase_66 | AC | 97 ms
24,300 KB |
testcase_67 | AC | 90 ms
23,604 KB |
testcase_68 | AC | 97 ms
24,348 KB |
testcase_69 | AC | 98 ms
24,312 KB |
testcase_70 | AC | 99 ms
23,628 KB |
testcase_71 | AC | 98 ms
24,372 KB |
testcase_72 | AC | 97 ms
23,988 KB |
testcase_73 | AC | 88 ms
24,360 KB |
testcase_74 | AC | 97 ms
23,376 KB |
testcase_75 | AC | 97 ms
23,844 KB |
testcase_76 | AC | 97 ms
23,964 KB |
testcase_77 | AC | 93 ms
24,060 KB |
testcase_78 | AC | 60 ms
23,664 KB |
testcase_79 | AC | 88 ms
23,544 KB |
testcase_80 | AC | 94 ms
23,316 KB |
testcase_81 | AC | 86 ms
23,328 KB |
testcase_82 | AC | 93 ms
23,640 KB |
testcase_83 | AC | 97 ms
24,312 KB |
testcase_84 | AC | 96 ms
23,976 KB |
testcase_85 | AC | 97 ms
23,964 KB |
testcase_86 | AC | 87 ms
23,844 KB |
testcase_87 | AC | 91 ms
23,976 KB |
testcase_88 | AC | 93 ms
23,580 KB |
testcase_89 | AC | 95 ms
23,856 KB |
testcase_90 | AC | 108 ms
23,388 KB |
testcase_91 | AC | 93 ms
23,640 KB |
testcase_92 | AC | 82 ms
23,988 KB |
testcase_93 | AC | 49 ms
23,376 KB |
testcase_94 | AC | 96 ms
23,976 KB |
testcase_95 | AC | 97 ms
23,484 KB |
testcase_96 | AC | 95 ms
23,964 KB |
testcase_97 | AC | 97 ms
23,820 KB |
testcase_98 | AC | 98 ms
23,940 KB |
testcase_99 | AC | 88 ms
23,376 KB |
コンパイルメッセージ
warning: unused variable: `y` --> Main.rs:370:21 | 370 | for y in (0..Y).rev() { | ^ help: if this is intentional, prefix it with an underscore: `_y` | = note: `#[warn(unused_variables)]` on by default warning: variable does not need to be mutable --> Main.rs:57:7 | 57 | let mut it = line.split_whitespace(); | ----^^ | | | help: remove this `mut` ... 152 | let probs = read!([i8]); | ----------- in this macro invocation | = note: `#[warn(unused_mut)]` on by default = note: this warning originates in the macro `read` (in Nightly builds, run with -Z macro-backtrace for more info) warning: constant `SEED` is never used --> Main.rs:133:7 | 133 | const SEED: u32 = 890482; | ^^^^ | = note: `#[warn(dead_code)]` on by default warning: constant `TIME_LIMIT` is never used --> Main.rs:134:7 | 134 | const TIME_LIMIT: f64 = 1.9; | ^^^^^^^^^^ warning: function `read_probs` is never used --> Main.rs:151:4 | 151 | fn read_probs() -> Vec<i8> { | ^^^^^^^^^^ warning: 5 warnings emitted
ソースコード
//-------------------------------------------------------------------------------- #[allow(unused_macros)] macro_rules! debug { ($($a:expr),*) => { #[cfg(feature = "single_testcase")] { eprint!("[line:{}] ", line!()); eprintln!(concat!($(stringify!($a), " = {:?}, "),*), $($a),*); } } } fn get_time() -> f64 { static mut STIME: f64 = -1.0; let t = std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap(); let ms = t.as_secs() as f64 + t.subsec_nanos() as f64 * 1e-9; unsafe { if STIME < 0.0 { STIME = ms; } ms - STIME } } //-------------------------------------------------------------------------------- // https://atcoder.jp/contests/intro-heuristics/submissions/14832097 // let D = read!(usize); // let c = read!([i64]); // let s = read!([i64]; D); // let (n, m) = read!(i32, i32); #[allow(dead_code)] fn readln() -> String { let mut line = String::new(); ::std::io::stdin() .read_line(&mut line) .unwrap_or_else(|e| panic!("{}", e)); line } #[allow(unused_macros)] macro_rules! read { ($($t:tt),*; $n:expr) => {{ let stdin = ::std::io::stdin(); let ret = ::std::io::BufRead::lines(stdin.lock()).take($n).map(|line| { let line = line.unwrap(); let mut it = line.split_whitespace(); _read!(it; $($t),*) }).collect::<Vec<_>>(); ret }}; ($($t:tt),*) => {{ let line = readln(); let mut it = line.split_whitespace(); _read!(it; $($t),*) }}; } macro_rules! _read { ($it:ident; [char]) => { _read!($it; String).chars().collect::<Vec<_>>() }; ($it:ident; [u8]) => { Vec::from(_read!($it; String).into_bytes()) }; ($it:ident; usize1) => { $it.next().unwrap_or_else(|| panic!("input mismatch")).parse::<usize>().unwrap_or_else(|e| panic!("{}", e)) - 1 }; ($it:ident; [usize1]) => { $it.map(|s| s.parse::<usize>().unwrap_or_else(|e| panic!("{}", e)) - 1).collect::<Vec<_>>() }; ($it:ident; [$t:ty]) => { $it.map(|s| s.parse::<$t>().unwrap_or_else(|e| panic!("{}", e))).collect::<Vec<_>>() }; ($it:ident; $t:ty) => { $it.next().unwrap_or_else(|| panic!("input mismatch")).parse::<$t>().unwrap_or_else(|e| panic!("{}", e)) }; ($it:ident; $($t:tt),+) => { ($(_read!($it; $t)),*) }; } //-------------------------------------------------------------------------------- // https://atcoder.jp/contests/hokudai-hitachi2017-1/submissions/1797182 // u32 -> usize pub struct XorShift { pub x: [usize; 4], } impl XorShift { pub fn new(mut seed: usize) -> XorShift { let mut x = [0; 4]; for i in 0..4 { seed = 1812433253usize .wrapping_mul(seed ^ (seed >> 30)) .wrapping_add(i as usize); x[i] = seed; } XorShift { x } } pub fn next_usize(&mut self) -> usize { let t = self.x[0] ^ (self.x[0] << 11); for i in 0..3 { self.x[i] = self.x[i + 1] } self.x[3] = self.x[3] ^ (self.x[3] >> 19) ^ t ^ (t >> 8); self.x[3] } /// [0, n) pub fn next(&mut self, n: usize) -> usize { loop { let t = self.next_usize(); let r = t % n; if (t - r).checked_add(n).is_some() { return r; } } } pub fn shuffle<T>(&mut self, a: &mut [T]) { for i in 0..a.len() { let j = i + self.next(a.len() - i) as usize; a.swap(i, j); } } } //-------------------------------------------------------------------------------- const SEED: u32 = 890482; const TIME_LIMIT: f64 = 1.9; const INF: usize = 1_000_000_000; const NUM_TURNS: usize = 1000; const X: usize = 25; const Y: usize = 60; #[derive(Debug, Clone, Copy, PartialEq, Eq)] struct Enemy { x: usize, y: usize, init_hp: i32, hp: i32, power: i32, } fn read_probs() -> Vec<i8> { let probs = read!([i8]); probs } fn read_input() -> Option<Vec<Enemy>> { let n = read!(i8); if n == -1 { None } else { let mut enemys = vec![]; for _ in 0..n { let (init_hp, power, x) = read!(i32, i32, usize); enemys.push(Enemy { x, y: Y - 1, init_hp, hp: init_hp, power}); } Some(enemys) } } #[derive(Debug)] struct Player { x: usize, y: usize, score: i32, power: i32, level: i32, } #[derive(Debug)] struct State { board: [[Option<Enemy>; X]; Y], player: Player, } impl State { fn new() -> Self { let board = [[None; X]; Y]; let player = Player { x: X / 2, y: 0, score: 0, power: 0, level: 1 }; Self { board, player } } fn update_before(&mut self, enemys: Vec<Enemy>) -> bool { // 敵機の更新 for y in 0..Y - 1 { for x in 0..X { self.board[y][x] = self.board[y+1][x]; if let Some(enemy) = &mut self.board[y][x] { enemy.y -= 1; } } } for x in 0..X { self.board[Y-1][x] = None; } for enemy in enemys.into_iter() { self.board[Y-1][enemy.x] = Some(enemy); } if let Some(_enemy) = self.board[self.player.y][self.player.x] { false } else { true } } fn update_after(&mut self, command: char) { // 移動 if command == 'L' { if self.player.x == 0 { self.player.x = X - 1; } else { self.player.x -= 1; } } else if command == 'R' { if self.player.x == X - 1 { self.player.x = 0; } else { self.player.x += 1; } } else if command == 'S' { // Stay } else { unreachable!(); } // 攻撃 for y in 1..Y { if let Some(enemy) = &mut self.board[y][self.player.x] { debug!(enemy); enemy.hp -= self.player.level; if enemy.hp <= 0 { // 破壊した self.player.score += enemy.init_hp; self.player.power += enemy.power; self.player.level = 1 + self.player.power / 100; self.board[y][self.player.x] = None; } break; } } } } fn solve(state: &State, turn: usize) -> char { let mut max_eval_score = 0.0; let mut max_command = 'S'; let mut max_enemy = None; for x in 0..X { let mut arrive_dturn = INF; let mut command = 'S'; if x == state.player.x { arrive_dturn = 0; command = 'S'; } else { let mut min_dturn = INF; let mut min_command = 'S'; for &dx in [!0, 1].iter() { let mut now_x = state.player.x; let mut cmd = 'S'; for dturn in 1..=NUM_TURNS - turn { let next_x = now_x.wrapping_add(dx) % X; let no_conflict_0 = dturn - 1 >= Y || state.board[dturn - 1][next_x] == None; let no_conflict_1 = dturn >= Y || (state.board[dturn][next_x] == None || state.board[dturn][next_x].unwrap().hp <= state.player.level); if no_conflict_0 && no_conflict_1 { now_x = next_x; } if dturn == 1 { if no_conflict_0 && no_conflict_1 { cmd = if dx == !0 { 'L' } else { 'R' }; } else { cmd = 'S'; } } if now_x == x { if dturn < min_dturn { min_dturn = dturn; min_command = cmd; } break; } } } if min_dturn != INF { arrive_dturn = min_dturn; command = min_command; } } // debug!(x, arrive_dturn, command); if arrive_dturn < Y { let t = turn as f64 / NUM_TURNS as f64; for y in arrive_dturn..Y { if let Some(enemy) = state.board[y][x] { if (enemy.hp + state.player.level - 1) / state.player.level <= (y - arrive_dturn) as i32{ // 破壊できる let destroy_dturn = arrive_dturn as i32 + (enemy.hp + state.player.level - 1) / state.player.level; let eval_score = (t * enemy.init_hp as f64 + (1.0 - t) * (enemy.power * enemy.power) as f64 / 10000.0) / destroy_dturn as f64; if eval_score > max_eval_score { max_eval_score = eval_score; max_command = command; max_enemy = Some(enemy); } } break; } } } } if max_enemy == None { if let Some(_enemy) = state.board[1][state.player.x] { let lx = state.player.x.wrapping_add(!0) % X; if state.board[0][lx] == None && state.board[1][lx] == None { max_command = 'L'; } else { max_command = 'R'; } } } debug!(max_eval_score, max_command, max_enemy); max_command } fn main() { get_time(); #[cfg(feature = "single_testcase")] read_probs(); let mut state = State::new(); for turn in 1..=NUM_TURNS { // if turn == 5 { // break; // } // debug!(state.board[2]); // debug!(state.board[1]); // debug!(state.board[0]); let enemys = read_input(); match enemys { Some(enemys) => { let ok = state.update_before(enemys); if !ok { debug!(turn); break; } debug!(turn, state.player); for y in (0..Y).rev() { debug!(y, state.board[y]); break; } let command = solve(&state, turn); eprintln!("{}", command); println!("{}", command); state.update_after(command); }, None => break, } } debug!(state.player.score); eprintln!("time_elapsed: {:.3}", get_time()); }