結果
問題 |
No.3121 Prime Dance
|
ユーザー |
![]() |
提出日時 | 2025-04-20 14:43:01 |
言語 | Rust (1.83.0 + proconio) |
結果 |
AC
|
実行時間 | 671 ms / 2,000 ms |
コード長 | 4,795 bytes |
コンパイル時間 | 13,160 ms |
コンパイル使用メモリ | 404,352 KB |
実行使用メモリ | 144,640 KB |
最終ジャッジ日時 | 2025-04-20 14:43:25 |
合計ジャッジ時間 | 20,004 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 21 |
ソースコード
#![allow( dead_code, non_snake_case, unused_imports, unused_mut, unused_variables, while_true, unused_assignments, clippy::needless_range_loop, clippy::ptr_arg, clippy::type_complexity, clippy::unnecessary_cast )] use proconio::{ input, marker::{Chars, Usize1 as usize1}, source::line::LineSource, }; use std::collections::{BinaryHeap, HashMap, HashSet, VecDeque}; use std::io::{BufReader, Write, stdin, stdout}; use std::mem::{swap, take}; macro_rules! mat { ($elem:expr; $n:expr) => { vec![$elem; $n] }; ($elem:expr; $dim0:expr; $($dim:expr);*) => { vec![mat![$elem; $($dim);*]; $dim0] }; } const D4X: [isize; 4] = [-1, 0, 1, 0]; const D4Y: [isize; 4] = [0, 1, 0, -1]; fn is_prime(n: usize) -> bool { if n < 2 { return false; } for i in 2..=((n as f64).sqrt() as usize) { if n % i == 0 { return false; } } true } fn find_best(mut a: usize, mut b: usize) -> Option<usize> { let k = a.abs_diff(b); if k % 2 == 1 { let m = a.min(b); let u = 2_usize.saturating_sub(m); a += u; b += u; if !is_prime(a) || !is_prime(b) { return None; } return Some(u); } let mut u = 0; while !is_prime(a) || !is_prime(b) { a += 1; b += 1; u += 1; } Some(u) } fn main() { input! { H: usize, W: usize, mut Sy: usize1, mut Sx: usize1, mut Gy: usize1, mut Gx: usize1, mut C: [Chars; H], }; if Sx > Gx { Sx = W - 1 - Sx; Gx = W - 1 - Gx; for i in 0..H { C[i].reverse(); } } if Sy > Gy { Sy = H - 1 - Sy; Gy = H - 1 - Gy; C.reverse(); } // 01BFS let inf = 1_000_000_000; let mut dist = mat![inf; H; W; H * W + 1; 2]; let mut que = VecDeque::new(); que.push_front((Sy, Sx, 0, 0, 0)); dist[Sy][Sx][0][0] = 0; while let Some((y, x, use_down, did_lr, c)) = que.pop_front() { if dist[y][x][use_down][did_lr] < c { continue; } for dir in 0..4 { let ny = y as isize + D4Y[dir]; let nx = x as isize + D4X[dir]; if ny < 0 || ny >= H as isize || nx < 0 || nx >= W as isize { continue; } let ny = ny as usize; let nx = nx as usize; if C[ny][nx] == '#' { continue; } let c_down = if D4Y[dir] == 1 { 1 } else { 0 }; let c_right = if D4X[dir] == 1 { 1 } else { 0 }; let use_down = use_down + c_down; if use_down > H * W { continue; } let nc = c + c_right; // if y == 0 && x == 0 && c == 0 && use_down == 1 { // dbg!(ny, nx, nc, c_down); // dbg!(dist[ny][nx][use_down]); // } let n_did_lr = did_lr.max(c_right); if dist[ny][nx][use_down][n_did_lr] > nc { dist[ny][nx][use_down][n_did_lr] = nc; if c_right == 0 { que.push_front((ny, nx, use_down, n_did_lr, nc)); } else { que.push_back((ny, nx, use_down, n_did_lr, nc)); } } } } let mut ans = inf; for u_d in 0..=H * W { for did_lr in 0..=1 { let u_r = dist[Gy][Gx][u_d][did_lr]; if u_r == inf { continue; } if u_r < (Gx - Sx) { continue; } if u_d < (Gy - Sy) { continue; } let u_l = u_r - (Gx - Sx); let u_u = u_d - (Gy - Sy); let mut cur = u_d + u_r + u_l + u_u; // if u_d == 1 { // dbg!(cur); // dbg!((u_d, u_u, u_r, u_l)); // dbg!(find_best(0, 2)); // } match find_best(u_d, u_u) { Some(u) => { if u > 0 && u_d == 0 && u_u == 0 { continue; } cur += u * 2; } None => { continue; } } match find_best(u_r, u_l) { Some(u) => { if u > 0 && u_l == 0 && u_r == 0 { continue; } cur += u * 2; } None => { continue; } } ans = ans.min(cur); } } if ans == inf { println!("-1"); } else { println!("{}", ans); } }