結果
問題 | No.5017 Tool-assisted Shooting |
ユーザー |
|
提出日時 | 2023-07-16 19:13:51 |
言語 | Rust (1.83.0 + proconio) |
結果 |
AC
|
実行時間 | 99 ms / 2,000 ms |
コード長 | 5,590 bytes |
コンパイル時間 | 1,951 ms |
コンパイル使用メモリ | 164,092 KB |
実行使用メモリ | 24,432 KB |
スコア | 74,830 |
平均クエリ数 | 399.74 |
最終ジャッジ日時 | 2023-07-16 19:14:05 |
合計ジャッジ時間 | 12,365 ms |
ジャッジサーバーID (参考情報) |
judge17 / judge13 |
純コード判定しない問題か言語 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 100 |
ソースコード
use std::{collections::HashMap,io::{stdin, stdout, Write},};const H: usize = 60;const W: usize = 25;// type Output = Vec<char>;fn main() {let mut sim = Sim::new();for _ in 1..=1000 {if let Some(input) = read_input() {sim.proceed(input.es, 'S');println!("S");stdout().flush().unwrap();if sim.is_defeat {break;}} else {break;}}}fn read_input() -> Option<Input> {let mut n = String::new();stdin().read_line(&mut n).unwrap();if n.trim() == "-1" {return None;}let n = n.trim().parse::<usize>().unwrap();let mut es = vec![];for _ in 0..n {let mut line = String::new();stdin().read_line(&mut line).unwrap();let mut tokens = line.split_whitespace();let h = tokens.next().unwrap().parse::<i64>().unwrap();let p = tokens.next().unwrap().parse::<i64>().unwrap();let x = tokens.next().unwrap().parse::<usize>().unwrap();es.push((h, p, x));}Some(Input { n, es })}#[allow(dead_code)]#[derive(Debug)]struct Input {n: usize,es: Vec<(i64, i64, usize)>,}#[derive(Debug, Clone, Copy)]pub struct Player {s: i64,pos_x: usize,}impl Player {pub fn new() -> Self {Player { s: 0, pos_x: 12 }}pub fn level(&self) -> i64 {1 + self.s / 100}}impl Default for Player {fn default() -> Self {Self::new()}}struct Enemy {hp: i64,dameged: i64,power: i64,}impl Enemy {pub fn new(hp: i64, power: i64) -> Self {Self {hp,dameged: 0,power,}}}pub struct Sim {board: Vec<Vec<Square>>,player: Player,enemies: HashMap<usize, Enemy>,score: i64,is_defeat: bool,}impl Sim {pub fn new() -> Self {let mut board = vec![vec![Square::EMPTY; W]; H];board[0][12] = Square::PLAYER;let player = Player::new();let enemies = HashMap::new();Self {board,player,enemies,score: 0,is_defeat: false,}}pub fn proceed(&mut self, es: Vec<(i64, i64, usize)>, command: char) {// 全enemyが一段下にfor h in 0..H {for w in 0..W {if let Square::ENEMY { id: _ } = self.board[h][w] {if h != 0 {if Square::PLAYER == self.board[h - 1][w] {self.is_defeat = true;}self.board[h - 1][w] = self.board[h][w];}self.board[h][w] = Square::EMPTY;}}}// 新たなenemyが出現for (h, p, x) in es {let id = self.enemies.len() + 1;self.board[H - 1][x] = Square::ENEMY { id };self.enemies.insert(id, Enemy::new(h, p));}// playerが移動match command {'L' => {let prev_x = self.player.pos_x;let next_x = (self.player.pos_x + W - 1) % W;if let Square::ENEMY { id: _ } = self.board[0][next_x] {self.is_defeat = true;} else {self.board[0][next_x] = self.board[0][prev_x];}self.board[0][prev_x] = Square::EMPTY;self.player.pos_x = next_x;}'R' => {let prev_x = self.player.pos_x;let next_x = (self.player.pos_x + W + 1) % W;self.player.pos_x = next_x;if let Square::ENEMY { id: _ } = self.board[0][next_x] {self.is_defeat = true;} else {self.board[0][next_x] = self.board[0][prev_x];}self.board[0][prev_x] = Square::EMPTY;self.player.pos_x = next_x;}'S' => {}_ => unreachable!(),}// playerによる攻撃if !self.is_defeat {for h in 1..H {if let Square::ENEMY { id } = self.board[h][self.player.pos_x] {let enemy = self.enemies.get_mut(&id).unwrap();enemy.dameged += self.player.level();// eprintln!("id: {}", id);// eprintln!("initial hp: {}", enemy.hp);// eprintln!(// "hp: {}",// if enemy.hp <= enemy.dameged {// 0// } else {// enemy.hp - enemy.dameged// }// );// eprintln!("power: {}", enemy.power);// eprintln!("pos: ({}, {})", self.player.pos_x, h);// eprintln!();if enemy.hp <= enemy.dameged {self.player.s += enemy.power;self.score += enemy.hp;self.board[h][self.player.pos_x] = Square::EMPTY;}break;}}}}}impl Default for Sim {fn default() -> Self {Self::new()}}#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]pub enum Square {PLAYER,ENEMY { id: usize },EMPTY,}