From 5b238eb7947992fbddfeae540ff2d6fbeb24c1de Mon Sep 17 00:00:00 2001 From: yenru0 Date: Fri, 28 Nov 2025 16:03:43 +0900 Subject: [PATCH] complete 1799.rs --- storage/zeta/rs/completed/1799.rs | 161 ++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 storage/zeta/rs/completed/1799.rs diff --git a/storage/zeta/rs/completed/1799.rs b/storage/zeta/rs/completed/1799.rs new file mode 100644 index 0000000..59fa171 --- /dev/null +++ b/storage/zeta/rs/completed/1799.rs @@ -0,0 +1,161 @@ +use std::io::stdin; + +pub struct Field { + n: usize, + data: Vec>, +} + +impl Field { + pub fn new(n: usize, data: Vec>) -> Self { + Self { n, data } + } + + pub fn clone(&self) -> Self { + Self { + n: self.n, + data: self.data.clone(), + } + } + + pub fn next_availables(&self, cur_ru: usize) -> Vec<(usize, usize)> { + let mut availables = vec![]; + + let mut ru = cur_ru; + while availables.is_empty() && ru <= 2 * self.n - 1 { + for i in (0..(ru + 1)).rev() { + let j = ru - i; + if i < self.n && j < self.n && self.data[i][j] { + availables.push((i, j)); + } + } + ru += 1; + } + + availables + } + + pub fn make_bishop(&self, point: (usize, usize)) -> Self { + let mut new_data = self.data.clone(); + new_data[point.0][point.1] = false; + + let directions: [(isize, isize); 1] = [(1, 1)]; + for direction in directions.iter() { + let mut x = point.0 as isize; + let mut y = point.1 as isize; + + loop { + x += direction.0; + y += direction.1; + + if x < 0 || x >= self.n as isize || y < 0 || y >= self.n as isize { + break; + } + + new_data[x as usize][y as usize] = false; + } + } + + Self { + n: self.n, + data: new_data, + } + } + + pub fn print(&self) { + for i in 0..self.n { + for j in 0..self.n { + if self.data[i][j] { + print!("1 "); + } else { + print!("0 "); + } + } + println!(); + } + } +} + +pub enum Instruction { + Make( + (usize, usize), // 착수 위치 + ), // 비숍을 착수하고 다음 스택프레임을 만듬 + Backtrack, // 현재 스택프레임을 파괴하고 이전 프레임으로 돌아감 +} + +fn solve(n: usize, init_field_data: Vec>) -> u64 { + let mut history: Vec = vec![]; + let mut stack: Vec = vec![]; + let field = Field::new(n, init_field_data); + + let mut max_bishop_count = 0u64; + history.push(field); + + stack.push(Instruction::Backtrack); + for availables in history.last().unwrap().next_availables(0) { + stack.push(Instruction::Make(availables)); + } + + while !stack.is_empty() { + let instruction = stack.pop().unwrap(); + + match instruction { + Instruction::Make(point) => { + let current_field = history.last().unwrap(); + let new_field = current_field.make_bishop(point); + + history.push(new_field); + + // 해지해야함 + stack.push(Instruction::Backtrack); + let next_availables = history + .last() + .unwrap() + .next_availables(point.0 + point.1 + 1); + if next_availables.is_empty() { + let bishop_count = history.len() as u64 - 1; + if bishop_count > max_bishop_count { + max_bishop_count = bishop_count; + } + } else { + for next_point in next_availables { + stack.push(Instruction::Make(next_point)); + } + } + } + Instruction::Backtrack => { + history.pop(); + } + } + } + + max_bishop_count +} + +fn main() { + let mut line = String::new(); + stdin().read_line(&mut line).unwrap(); + + let n: usize = line.trim().parse().unwrap(); + + let mut available_point: Vec<(usize, usize)> = vec![]; + + let field_data = (0..n) + .map(|i| { + line.clear(); + stdin().read_line(&mut line).unwrap(); + let mut iter = line + .split(' ') + .map(|x| x.trim_ascii_end().parse::().unwrap() == 1); + + (0..n) + .map(|j| { + available_point.push((i, j)); + iter.next().unwrap() + }) + .collect::>() + }) + .collect::>>(); + + let res = solve(n, field_data); + println!("{}", res); +}