結果

問題 No.3121 Prime Dance
ユーザー lumc_
提出日時 2025-04-20 13:53:07
言語 Rust
(1.83.0 + proconio)
結果
WA  
実行時間 -
コード長 4,360 bytes
コンパイル時間 29,479 ms
コンパイル使用メモリ 404,096 KB
実行使用メモリ 24,192 KB
最終ジャッジ日時 2025-04-20 13:53:39
合計ジャッジ時間 15,120 ms
ジャッジサーバーID
(参考情報)
judge4 / judge1
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 2
other AC * 17 WA * 4
権限があれば一括ダウンロードができます

ソースコード

diff #

#![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 Sx: usize1, mut Sy: usize1,
        mut Gx: usize1, mut Gy: usize1,
        mut C: [Chars; H],
    };

    if Sy > Gy {
        Sy = W - 1 - Sy;
        Gy = W - 1 - Gy;
        for i in 0..H {
            C[i].reverse();
        }
    }
    if Sx > Gx {
        Sx = H - 1 - Sx;
        Gx = H - 1 - Gx;
        C.reverse();
    }

    // 01BFS
    let inf = (H * W).pow(2);
    let mut dist = mat![inf; H; W; H * W + 1];
    let mut que = VecDeque::new();
    que.push_front((Sx, Sy, 0, 0));
    dist[Sx][Sy][0] = 0;
    while let Some((x, y, use_down, c)) = que.pop_front() {
        if dist[x][y][use_down] < c {
            continue;
        }
        if x == Gx && y == Gy {
            continue;
        }
        for dir in 0..4 {
            let nx = x as isize + D4X[dir];
            let ny = y as isize + D4Y[dir];
            if nx < 0 || nx >= H as isize || ny < 0 || ny >= W as isize {
                continue;
            }
            let nx = nx as usize;
            let ny = ny as usize;
            if C[nx][ny] == '#' {
                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 dist[nx][ny][use_down] > nc {
                dist[nx][ny][use_down] = nc;
                if c_right == 0 {
                    que.push_front((nx, ny, use_down, nc));
                } else {
                    que.push_back((nx, ny, use_down, nc));
                }
            }
        }
    }

    let mut ans = inf;
    for u_d in 0..=H * W {
        let u_r = dist[Gx][Gy][u_d];
        if u_r == inf {
            continue;
        }
        if u_r < (Gy - Sy) {
            continue;
        }
        if u_d < (Gx - Sx) {
            continue;
        }
        let u_l = u_r - (Gy - Sy);
        let u_u = u_d - (Gx - Sx);
        let mut cur = u_d + u_r + u_l + u_u;
        // if u_d == 5 {
        //     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);
    }
}
0