From ca687d0d736bc7467b30767845b9d36588745b2d Mon Sep 17 00:00:00 2001 From: jackfiled Date: Thu, 20 Mar 2025 12:33:35 +0800 Subject: [PATCH] 20250320 finished. --- src/problem/mod.rs | 2 + ...n_array_into_a_2d_array_with_conditions.rs | 4 +- .../p2612_minimum_reverse_operations.rs | 89 +++++++++++++++++++ src/util/mod.rs | 2 + src/util/vec_equal.rs | 51 +++++++++++ 5 files changed, 146 insertions(+), 2 deletions(-) create mode 100644 src/problem/p2612_minimum_reverse_operations.rs create mode 100644 src/util/vec_equal.rs diff --git a/src/problem/mod.rs b/src/problem/mod.rs index a25aa92..f27cfd1 100644 --- a/src/problem/mod.rs +++ b/src/problem/mod.rs @@ -548,3 +548,5 @@ mod p1963_minimum_number_of_swaps_to_make_the_string_balanced; mod p2614_prime_in_diagonal; mod p2610_convert_an_array_into_a_2d_array_with_conditions; + +mod p2612_minimum_reverse_operations; diff --git a/src/problem/p2610_convert_an_array_into_a_2d_array_with_conditions.rs b/src/problem/p2610_convert_an_array_into_a_2d_array_with_conditions.rs index 0d9ef6f..b97f46c 100644 --- a/src/problem/p2610_convert_an_array_into_a_2d_array_with_conditions.rs +++ b/src/problem/p2610_convert_an_array_into_a_2d_array_with_conditions.rs @@ -39,9 +39,9 @@ mod tests { #[test] fn test_2610() { - assert_eq!( + assert_inner_array_unorder_equal!( vec![vec![1, 3, 4, 2], vec![1, 3], vec![1]], - Solution::find_matrix(vec![1, 3, 4, 1, 2, 3, 1]) + Solution::find_matrix(vec![1, 3, 4, 1, 2, 3, 1]), ); } } diff --git a/src/problem/p2612_minimum_reverse_operations.rs b/src/problem/p2612_minimum_reverse_operations.rs new file mode 100644 index 0000000..dcaf5b3 --- /dev/null +++ b/src/problem/p2612_minimum_reverse_operations.rs @@ -0,0 +1,89 @@ +/** + * [2612] Minimum Reverse Operations + */ +pub struct Solution {} + +// submission codes start here +use std::collections::{BTreeSet, HashSet, VecDeque}; +use std::iter::FromIterator; + +impl Solution { + pub fn min_reverse_operations(n: i32, p: i32, banned: Vec, k: i32) -> Vec { + let (n, p) = (n as usize, p as usize); + let mut ban_pos: HashSet = + HashSet::from_iter(banned.into_iter().map(|x| x as usize)); + // 奇数下标和偶数下标是分别连续的 + // 使用两个二叉树维护 + let mut odd_pos = BTreeSet::new(); + let mut even_pos = BTreeSet::new(); + + for i in 0..n { + if i != p && !ban_pos.contains(&i) { + if i % 2 == 0 { + even_pos.insert(i); + } else { + odd_pos.insert(i); + } + } + } + + let mut result = vec![-1; n]; + let mut queue = VecDeque::new(); + queue.push_back(p); + result[p] = 0; + + while let Some(front) = queue.pop_front() { + // 为了防止usize溢出的诡异类型转换 + let min_pos = (front as i32 - k + 1).max(k - front as i32 - 1) as usize; + let max_pos = (front as i32 + k - 1).min(n as i32 * 2 - k - front as i32 - 1) as usize; + + let mut iter = if max_pos % 2 == 0 { + even_pos.range(min_pos..) + } else { + odd_pos.range(min_pos..) + }; + + while let Some(&value) = iter.next() { + if value > max_pos { + break; + } + + result[value] = result[front] + 1; + queue.push_back(value); + + iter = if min_pos % 2 == 0 { + even_pos.remove(&value); + even_pos.range(value + 1..) + } else { + odd_pos.remove(&value); + odd_pos.range(value + 1..) + } + } + } + + result + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_2612() { + assert_eq!( + vec![0, -1, -1, 1], + Solution::min_reverse_operations(4, 0, vec![1, 2], 4) + ); + assert_eq!( + vec![0, -1, -1, -1, -1], + Solution::min_reverse_operations(5, 0, vec![2, 4], 3) + ); + assert_eq!( + vec![-1, -1, 0, -1], + Solution::min_reverse_operations(4, 2, vec![0, 1, 3], 1) + ); + } +} diff --git a/src/util/mod.rs b/src/util/mod.rs index 5a3e574..393b4ec 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -6,3 +6,5 @@ pub mod vec_string; pub mod tree; #[macro_use] pub mod point; +#[macro_use] +pub mod vec_equal; diff --git a/src/util/vec_equal.rs b/src/util/vec_equal.rs new file mode 100644 index 0000000..b84fc69 --- /dev/null +++ b/src/util/vec_equal.rs @@ -0,0 +1,51 @@ +use std::collections::HashSet; +use std::hash::Hash; +use std::iter::FromIterator; + +pub fn assert_array_unorder_equal(a: &Vec, b: &Vec) +where + T: Eq, + T: Hash, +{ + assert_eq!(a.len(), b.len()); + + let set: HashSet<&T> = HashSet::from_iter(a.into_iter()); + + for i in b.iter() { + assert!(set.contains(i)); + } +} + +#[macro_export] +macro_rules! assert_array_unorder_equal { + ($left:expr, $right:expr $(,)?) => { + match (&$left, &$right) { + (left_value, right_value) => { + $crate::util::vec_equal::assert_array_unorder_equal(left_value, right_value); + } + } + }; +} + +pub fn assert_inner_array_unorder_equal(a: &Vec>, b: &Vec>) +where + T: Eq, + T: Hash, +{ + assert_eq!(a.len(), b.len()); + + for (i, j) in a.iter().zip(b.iter()) { + assert_array_unorder_equal(i, j); + } +} + +#[macro_export] +macro_rules! assert_inner_array_unorder_equal { + ($left:expr, $right:expr $(,)?) => { + match (&$left, &$right) { + (left_value, right_value) => { + $crate::util::vec_equal::assert_inner_array_unorder_equal(left_value, right_value); + } + } + }; +}