結果

問題 No.5006 Hidden Maze
ユーザー sca1lsca1l
提出日時 2022-06-12 16:05:50
言語 Rust
(1.77.0)
結果
AC  
実行時間 53 ms / 2,000 ms
コード長 6,603 bytes
コンパイル時間 986 ms
実行使用メモリ 22,868 KB
スコア 0
平均クエリ数 1001.00
最終ジャッジ日時 2022-06-12 16:08:18
合計ジャッジ時間 10,545 ms
ジャッジサーバーID
(参考情報)
judge11 / judge16
純コード判定しない問題か言語
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 48 ms
22,216 KB
testcase_01 AC 47 ms
21,892 KB
testcase_02 AC 47 ms
22,216 KB
testcase_03 AC 47 ms
22,444 KB
testcase_04 AC 48 ms
21,768 KB
testcase_05 AC 48 ms
21,904 KB
testcase_06 AC 48 ms
22,464 KB
testcase_07 AC 47 ms
21,928 KB
testcase_08 AC 47 ms
22,588 KB
testcase_09 AC 47 ms
21,892 KB
testcase_10 AC 49 ms
22,264 KB
testcase_11 AC 51 ms
22,588 KB
testcase_12 AC 48 ms
21,928 KB
testcase_13 AC 48 ms
21,880 KB
testcase_14 AC 48 ms
21,768 KB
testcase_15 AC 48 ms
21,868 KB
testcase_16 AC 50 ms
22,204 KB
testcase_17 AC 47 ms
22,276 KB
testcase_18 AC 48 ms
22,228 KB
testcase_19 AC 47 ms
21,904 KB
testcase_20 AC 48 ms
21,952 KB
testcase_21 AC 48 ms
21,892 KB
testcase_22 AC 48 ms
21,928 KB
testcase_23 AC 49 ms
22,216 KB
testcase_24 AC 49 ms
21,992 KB
testcase_25 AC 47 ms
21,768 KB
testcase_26 AC 46 ms
21,768 KB
testcase_27 AC 46 ms
22,444 KB
testcase_28 AC 47 ms
21,940 KB
testcase_29 AC 47 ms
22,612 KB
testcase_30 AC 48 ms
21,940 KB
testcase_31 AC 49 ms
21,780 KB
testcase_32 AC 48 ms
22,264 KB
testcase_33 AC 48 ms
22,552 KB
testcase_34 AC 47 ms
21,892 KB
testcase_35 AC 49 ms
21,928 KB
testcase_36 AC 48 ms
21,892 KB
testcase_37 AC 49 ms
22,868 KB
testcase_38 AC 47 ms
21,880 KB
testcase_39 AC 49 ms
21,928 KB
testcase_40 AC 49 ms
22,456 KB
testcase_41 AC 50 ms
21,808 KB
testcase_42 AC 48 ms
22,444 KB
testcase_43 AC 48 ms
21,928 KB
testcase_44 AC 47 ms
22,216 KB
testcase_45 AC 47 ms
21,768 KB
testcase_46 AC 47 ms
21,904 KB
testcase_47 AC 47 ms
21,756 KB
testcase_48 AC 48 ms
21,768 KB
testcase_49 AC 49 ms
22,444 KB
testcase_50 AC 50 ms
21,880 KB
testcase_51 AC 47 ms
21,756 KB
testcase_52 AC 48 ms
21,880 KB
testcase_53 AC 47 ms
21,768 KB
testcase_54 AC 47 ms
22,264 KB
testcase_55 AC 48 ms
21,892 KB
testcase_56 AC 47 ms
22,204 KB
testcase_57 AC 47 ms
21,928 KB
testcase_58 AC 46 ms
21,904 KB
testcase_59 AC 47 ms
21,880 KB
testcase_60 AC 47 ms
22,228 KB
testcase_61 AC 47 ms
22,204 KB
testcase_62 AC 48 ms
22,576 KB
testcase_63 AC 47 ms
22,264 KB
testcase_64 AC 48 ms
22,564 KB
testcase_65 AC 46 ms
21,892 KB
testcase_66 AC 48 ms
21,940 KB
testcase_67 AC 46 ms
21,672 KB
testcase_68 AC 46 ms
21,892 KB
testcase_69 AC 46 ms
21,992 KB
testcase_70 AC 48 ms
21,880 KB
testcase_71 AC 47 ms
21,980 KB
testcase_72 AC 47 ms
21,780 KB
testcase_73 AC 46 ms
21,768 KB
testcase_74 AC 48 ms
21,768 KB
testcase_75 AC 47 ms
21,892 KB
testcase_76 AC 46 ms
22,564 KB
testcase_77 AC 46 ms
21,992 KB
testcase_78 AC 47 ms
21,904 KB
testcase_79 AC 45 ms
21,768 KB
testcase_80 AC 53 ms
21,748 KB
testcase_81 AC 49 ms
21,904 KB
testcase_82 AC 48 ms
22,444 KB
testcase_83 AC 48 ms
22,444 KB
testcase_84 AC 49 ms
21,892 KB
testcase_85 AC 47 ms
22,704 KB
testcase_86 AC 49 ms
21,904 KB
testcase_87 AC 48 ms
22,612 KB
testcase_88 AC 46 ms
22,444 KB
testcase_89 AC 47 ms
21,940 KB
testcase_90 AC 47 ms
21,892 KB
testcase_91 AC 46 ms
21,780 KB
testcase_92 AC 47 ms
21,916 KB
testcase_93 AC 46 ms
22,608 KB
testcase_94 AC 47 ms
22,504 KB
testcase_95 AC 47 ms
21,992 KB
testcase_96 AC 47 ms
21,768 KB
testcase_97 AC 47 ms
21,780 KB
testcase_98 AC 47 ms
21,880 KB
testcase_99 AC 47 ms
21,980 KB
権限があれば一括ダウンロードができます
コンパイルメッセージ
warning: constant `delta` should have an upper case name
  --> Main.rs:26:7
   |
26 | const delta: Delta = Delta::new();
   |       ^^^^^ help: convert the identifier to upper case: `DELTA`
   |
   = note: `#[warn(non_upper_case_globals)]` on by default

warning: 1 warning emitted

ソースコード

diff #

#![allow(non_snake_case, dead_code, unused_imports, unused_macros)]

use std::collections::VecDeque;
use std::collections::BinaryHeap;
use std::cmp::Reverse;
use std::cmp::Ordering;
use std::cmp::{max, min};
use std::io::{stdout, Write};

const N: usize = 20;


struct Delta {
    pub y: [usize; 4],
    pub x: [usize; 4],
    pub d: [char; 4],
}
impl Delta {
    const fn new() -> Self {
        let y = [ !0,   0,   1,   0];
        let x = [  0,  !0,   0,   1];
        let d = ['U', 'L', 'D', 'R'];
        Delta{ y, x, d }
    }
}
const delta: Delta = Delta::new();

fn getline() -> String{
	let mut __ret = String::new();
	std::io::stdin().read_line(&mut __ret).ok();
	return __ret;
}


#[derive(Clone)]
struct State {
    pub move_cnt: Reverse<usize>,
    pub last_pos: usize,
    pub order: RcList<usize>,
}

impl State {
    fn new() -> Self {
        let move_cnt = Reverse(0);
        let last_pos = 0;
        let order = RcList::new();
        State{ move_cnt, last_pos, order}
    }
    
    fn move_next(&self, dir: usize) -> Self {
        let mut nproc = self.clone();
        nproc.move_cnt = Reverse(nproc.move_cnt.0 + 1);
        let ny = nproc.last_pos/N + delta.y[dir];
        let nx = nproc.last_pos%N + delta.x[dir];
        nproc.last_pos = ny*N+nx;
        nproc.order.push(dir);
        //
        nproc
    }
}

impl PartialOrd for State {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(&other))
    }
}

impl Ord for State {
    fn cmp(&self, other: &Self) -> Ordering {
        self.move_cnt.cmp(&other.move_cnt)
    }
}

impl PartialEq for State {
    fn eq(&self, other: &Self) -> bool {
        self.move_cnt == other.move_cnt
    }
}

impl Eq for State {
    //
}

fn solve() {
    let mut visited_pos = [false; N*N];
    visited_pos[0] = true;
    let mut heap: BinaryHeap<State> = BinaryHeap::new();
    heap.push(State::new());
    let mut second_heap: BinaryHeap<State> = BinaryHeap::new();
    
    'main: loop {
        if let Some(proc) = heap.pop() {
            let current_move_cnt = proc.move_cnt.0 as i32;
            let cy = proc.last_pos/N;
            let cx = proc.last_pos%N;
            let order_vec = proc.order.to_vec();
            for i in 0..4 {
                let ny = cy + delta.y[i];
                let nx = cx + delta.x[i];
                if !within_board(ny, nx) {
                    continue;
                }
                if visited_pos[ny*N+nx] {
                    continue;
                }
                //ok
                let mut cnt = 0;
                loop {
                    {
                        for &dir in order_vec.iter() {
                            print!("{}", delta.d[dir]);
                        }
                        print!("{}", delta.d[i]);
                        println!();
                        stdout().flush().unwrap();
                    }
                    {
                        let line = getline();
                        let input: i32 = line.trim().parse().unwrap();
                        if input < 0 {
                            //have to exit
                            break 'main;
                        } else if input == current_move_cnt + 1 {
                            //success
                            let nproc = proc.move_next(i);
                            visited_pos[nproc.last_pos] = true;
                            heap.push(nproc);
                            break;
                        } else if input == current_move_cnt {
                            //there is wall (perhaps)
                            cnt += 1;
                            if cnt < 3 {
                                continue;
                            } else {
                                second_heap.push(proc.clone());
                                break;
                            }
                        } else if input < current_move_cnt {
                            //just unlucky
                            continue;
                        }
                    }
                }
            }
        } else {
            heap = second_heap;
            second_heap = BinaryHeap::new();
        }
    }
    //
}

fn main() {
    let _ = getline();
    solve();
}

fn within_board(y: usize, x:usize) -> bool {
    y < N && x < N
}

fn manhattan_dist(ty: usize, tx: usize, py: usize, px: usize) -> usize {
    diff_abs(ty, py) + diff_abs(tx, px)
}

fn diff_abs(a: usize, b: usize) -> usize {
    max(a, b) - min(a, b)
}


//-----------------------------------------

#[derive(Debug)]
#[allow(dead_code)]
pub struct Xorshift {
    seed: u64,
}
impl Xorshift {
    #[allow(dead_code)]
    pub fn new() -> Xorshift {
        Xorshift {
            seed: 0xf0fb588ca2196dac,
        }
    }
    #[allow(dead_code)]
    pub fn with_seed(seed: u64) -> Xorshift {
        Xorshift { seed: seed }
    }
    #[inline]
    #[allow(dead_code)]
    pub fn next(&mut self) -> u64 {
        self.seed = self.seed ^ (self.seed << 13);
        self.seed = self.seed ^ (self.seed >> 7);
        self.seed = self.seed ^ (self.seed << 17);
        self.seed
    }
    #[inline]
    #[allow(dead_code)]
    pub fn rand_u64(&mut self, m: u64) -> u64 {
        self.next() % m
    }
    #[inline]
    #[allow(dead_code)]
    pub fn rand(&mut self, m: usize) -> usize {
        self.rand_u64(m as u64) as usize
    }
    #[inline]
    #[allow(dead_code)]
    // 0.0 ~ 1.0
    pub fn randf(&mut self) -> f64 {
        use std::mem;
        const UPPER_MASK: u64 = 0x3FF0000000000000;
        const LOWER_MASK: u64 = 0xFFFFFFFFFFFFF;
        let tmp = UPPER_MASK | (self.next() & LOWER_MASK);
        let result: f64 = unsafe { mem::transmute(tmp) };
        result - 1.0
    }
}

//------------------------------------

use std::rc::Rc;
#[derive(Debug)]
struct RcListInner<T> {
    parent: RcList<T>,
    value: T,
}
#[doc = "O(1) clone, O(1) push"]
#[derive(Clone, Debug)]
struct RcList<T>(Option<Rc<RcListInner<T>>>);
impl<T: Clone> RcList<T> {
    #[allow(dead_code)]
    fn new() -> Self {
        RcList(None)
    }
    #[allow(dead_code)]
    #[inline]
    fn push(&mut self, value: T) {
        *self = RcList(Some(Rc::new(RcListInner {
            parent: self.clone(),
            value,
        })));
    }
    #[allow(dead_code)]
    fn to_vec(&self) -> Vec<T> {
        if let Some(ref inner) = self.0 {
            let mut p = inner.parent.to_vec();
            p.push(inner.value.clone());
            p
        } else {
            Vec::new()
        }
    }
}

//-----------------------------------------
0