diff --git a/storage/zeta/rs/completed/16724.rs b/storage/zeta/rs/completed/16724.rs new file mode 100644 index 0000000..db111b4 --- /dev/null +++ b/storage/zeta/rs/completed/16724.rs @@ -0,0 +1,99 @@ +use std::io::stdin; + +fn interpret_map(size: (usize, usize), map_strings: &Vec) -> Vec { + let mut edges: Vec = vec![usize::MAX; size.0 * size.1]; + + for i in 0..size.0 { + let mut s = map_strings[i].chars(); + for j in 0..size.1 { + let c = s.next().unwrap(); + match c { + 'D' => { + if i != size.0 - 1 { + edges[i * size.1 + j] = (i + 1) * size.1 + j; + } + } + 'U' => { + if i != 0 { + edges[i * size.1 + j] = (i - 1) * size.1 + j; + } + } + 'L' => { + if j != 0 { + edges[i * size.1 + j] = i * size.1 + j - 1; + } + } + 'R' => { + if j != size.1 - 1 { + edges[i * size.1 + j] = i * size.1 + j + 1; + } + } + _ => {} + } + } + } + + edges +} + +fn disjoint_find(parents: &mut Vec, x: usize) -> usize { + let mut nd = x; + while nd != parents[nd] { + parents[nd] = parents[parents[nd]]; + nd = parents[nd]; + } + nd +} + +fn disjoint_union(parents: &mut Vec, x: usize, y: usize) -> bool { + let xr = disjoint_find(parents, x); + let yr = disjoint_find(parents, y); + if xr == yr { + return false; + } + if xr > yr { + parents[yr] = xr; + } else { + parents[xr] = yr; + } + true +} + +fn get_count_of_safezone(size: (usize, usize), edges: &Vec) -> usize { + let mut parents = (0..size.0 * size.1).collect::>(); + let mut cnt = size.0 * size.1; + for i in 0..size.0 * size.1 { + if edges[i] == usize::MAX { + continue; + } + if disjoint_union(&mut parents, i, edges[i]) { + cnt -= 1; + } + } + + cnt +} + +fn main() { + let mut line = String::new(); + stdin().read_line(&mut line).unwrap(); + + let mut iter = line.split_ascii_whitespace(); + let n = iter.next().unwrap().parse::().unwrap(); + let m = iter.next().unwrap().parse::().unwrap(); + + line.clear(); + + let map_strings = (0..n) + .map(|_| { + stdin().read_line(&mut line).unwrap(); + let t = line.trim().to_string(); + line.clear(); + t + }) + .collect::>(); + + let edges = interpret_map((n, m), &map_strings); + + println!("{}", get_count_of_safezone((n, m), &edges)); +} diff --git a/storage/zeta/rs/completed/17143.rs b/storage/zeta/rs/completed/17143.rs new file mode 100644 index 0000000..abe209c --- /dev/null +++ b/storage/zeta/rs/completed/17143.rs @@ -0,0 +1,280 @@ +use std::cmp::PartialEq; +use std::io::stdin; +use std::str::FromStr; + +#[repr(u8)] +#[derive(Clone, Copy, PartialEq, Debug)] +enum Direction { + Up = 1, + Down = 2, + Left = 4, + Right = 3, +} + +impl Direction { + fn reverse(&self) -> Self { + match self { + Self::Up => Self::Down, + Self::Down => Self::Up, + Self::Left => Self::Right, + Self::Right => Self::Left, + } + } + + fn is_horizontal(&self) -> bool { + match self { + Self::Up | Self::Down => true, + _ => false, + } + } +} + +impl TryFrom for Direction { + type Error = (); + + fn try_from(value: u8) -> Result { + match value { + 1 => Ok(Self::Up), + 2 => Ok(Self::Down), + 3 => Ok(Self::Right), + 4 => Ok(Self::Left), + _ => Err(()), + } + } +} + +impl FromStr for Direction { + type Err = (); + + fn from_str(value: &str) -> Result { + Direction::try_from(value.parse::().unwrap()) + } +} + +struct Shark { + pos: usize, + speed: u32, + direction: Direction, + size: u32, +} + +impl Shark { + fn new(size: &(usize, usize), r: usize, c: usize, s: u32, d: Direction, z: u32) -> Self { + Self { + pos: r * size.1 + c, + speed: s, + direction: if d.is_horizontal() { + if (c == 0 && d == Direction::Left) || c == size.1 - 1 && d == Direction::Right { + d.reverse() + } else { + d + } + } else { + if (r == 0 && d == Direction::Up) || r == size.0 - 1 && d == Direction::Down { + d.reverse() + } else { + d + } + }, + size: z, + } + } +} + +fn move_result(size: (usize, usize), shark: &Shark) -> (usize, Direction) { + let mut r = shark.pos / size.1; + let mut c = shark.pos % size.1; + + let mut dir: Direction = shark.direction; + + match dir { + Direction::Up => { + let remain_range = (size.0 - 1) * 2; + + let remain = shark.speed as usize % remain_range; + + let c1delta = r; + let c2delta = r + size.0 - 1; + + match remain { + rx if rx < c1delta => { + r -= remain; + } + rx if rx < c2delta => { + r = remain - c1delta; + dir = dir.reverse(); + } + + rx if rx < remain_range => { + r = size.0 - (remain - c2delta) - 1; + } + _ => {} + } + + (r * size.1 + c, dir) + } + + Direction::Down => { + let remain_range = (size.0 - 1) * 2; + + let remain = shark.speed as usize % remain_range; + + let c1delta = size.0 - r - 1; + let c2delta = 2 * size.0 - r - 2; + + match remain { + rx if rx < c1delta => { + r += remain; + } + rx if rx < c2delta => { + r = size.0 - (remain - c1delta) - 1; + dir = dir.reverse(); + } + rx if rx < remain_range => r = remain - c2delta, + _ => {} + } + + (r * size.1 + c, dir) + } + + Direction::Left => { + let remain_range = (size.1 - 1) * 2; + + let remain = shark.speed as usize % remain_range; + + let c1delta = c; + let c2delta = c + size.1 - 1; + + match remain { + rx if rx < c1delta => { + c -= remain; + } + rx if rx < c2delta => { + c = remain - c1delta; + dir = dir.reverse(); + } + + rx if rx < remain_range => { + c = size.1 - (remain - c2delta) - 1; + } + _ => {} + } + + (r * size.1 + c, dir) + } + Direction::Right => { + let remain_range = (size.1 - 1) * 2; + + let remain = shark.speed as usize % remain_range; + + let c1delta = size.1 - c - 1; + let c2delta = 2 * size.1 - c - 2; + + match remain { + rx if rx < c1delta => { + c += remain; + } + rx if rx < c2delta => { + c = size.1 - (remain - c1delta) - 1; + dir = dir.reverse(); + } + rx if rx < remain_range => c = remain - c2delta, + _ => {} + } + + (r * size.1 + c, dir) + } + } +} + +fn get_total_size_sharks_caught(size: (usize, usize), mut sharks: Vec) -> u32 { + let mut map: Vec = vec![usize::MAX; size.0 * size.1]; + + let mut exists = vec![true; sharks.len()]; + for (i, shark) in sharks.iter().enumerate() { + map[shark.pos] = i; + } + + fn update( + size: (usize, usize), + map: &mut Vec, + sharks: &mut Vec, + exists: &mut Vec, + ) { + // 이동 + let move_record = sharks + .iter() + .enumerate() + .filter(|&(i, _shark)| exists[i]) + .map(|(i, shark)| (i, shark.pos, move_result(size, shark))) + .collect::>(); + + let mut is_moved = vec![false; size.0 * size.1]; + for (i, pos, (new_pos, new_dir)) in move_record { + if !is_moved[pos] && pos != new_pos { + map[pos] = usize::MAX; + } + if is_moved[new_pos] == true { + if &sharks[map[new_pos]].size > &sharks[i].size { + exists[i] = false; + } else { + exists[map[new_pos]] = false; + map[new_pos] = i; + } + } else { + map[new_pos] = i; + is_moved[new_pos] = true; + } + + sharks[i].pos = new_pos; + sharks[i].direction = new_dir; + } + } + + let mut s: u32 = 0; + + for fisher_loc in 0..size.1 { + match (0..size.0) + .map(|i| map[i * size.1 + fisher_loc]) + .find(|&x| x != usize::MAX && exists[x]) + { + None => {} + Some(x) => { + s += sharks[x].size; + exists[x] = false; + } + }; + update(size, &mut map, &mut sharks, &mut exists); + } + + s +} + +fn main() { + let mut line = String::new(); + stdin().read_line(&mut line).unwrap(); + let mut iter = line.split_ascii_whitespace(); + let size: (usize, usize) = ( + iter.next().unwrap().parse().unwrap(), + iter.next().unwrap().parse().unwrap(), + ); + let num_sharks: usize = iter.next().unwrap().parse().unwrap(); + + let sharks = (0..num_sharks) + .map(|_| { + line.clear(); + stdin().read_line(&mut line).unwrap(); + let mut iter = line.split_ascii_whitespace(); + Shark::new( + &size, + iter.next().unwrap().parse::().unwrap() - 1, + iter.next().unwrap().parse::().unwrap() - 1, + iter.next().unwrap().parse::().unwrap(), // speed + iter.next().unwrap().parse::().unwrap(), // dir + iter.next().unwrap().parse::().unwrap(), // size + ) + }) + .collect::>(); + + println!("{}", get_total_size_sharks_caught(size, sharks)); +} diff --git a/storage/zeta/rs/completed/2056.rs b/storage/zeta/rs/completed/2056.rs new file mode 100644 index 0000000..7679f08 --- /dev/null +++ b/storage/zeta/rs/completed/2056.rs @@ -0,0 +1,169 @@ +use std::io::stdin; + +mod update_heap { + use std::cmp::Ordering; + + pub struct Task { + pub idx: usize, + pub remaining_time: usize, + } + + impl Task { + pub fn new(idx: usize, time: usize) -> Self { + Self { + idx, + remaining_time: time, + } + } + } + + impl PartialEq for Task { + fn eq(&self, other: &Self) -> bool { + self.remaining_time == other.remaining_time + } + } + + impl PartialOrd for Task { + fn partial_cmp(&self, other: &Self) -> Option { + self.remaining_time.partial_cmp(&other.remaining_time) + } + } + + pub struct UpdateHeap { + data: Vec, + } + + impl UpdateHeap { + pub fn new() -> Self { + Self { data: Vec::new() } + } + + pub fn is_empty(&self) -> bool { + self.data.is_empty() + } + + pub fn push(&mut self, item: Task) { + self.data.push(item); + let idx = self.data.len() - 1; + self.sift_up(idx); + } + + pub fn pop(&mut self) -> Option { + if self.is_empty() { + return None; + } + + let last_idx = self.data.len() - 1; + self.data.swap(0, last_idx); + let ret = self.data.pop().unwrap(); + if !self.data.is_empty() { + self.sift_down(0); + } + Some(ret) + } + + fn sift_up(&mut self, mut idx: usize) { + while idx > 0 { + let parent = (idx - 1) / 2; + if self.data[parent] > self.data[idx] { + self.data.swap(parent, idx); + idx = parent; + } else { + break; + } + } + } + + fn sift_down(&mut self, mut idx: usize) { + while idx < self.data.len() / 2 { + let left = 2 * idx + 1; + let right = 2 * idx + 2; + let mut child = left; + if right < self.data.len() && self.data[right] < self.data[left] { + child = right; + } + if self.data[child] < self.data[idx] { + self.data.swap(child, idx); + idx = child; + } else { + break; + } + } + } + + pub fn update(&mut self, dt: usize) { + self.data.iter_mut().for_each(|x| x.remaining_time -= dt); + } + } +} + +use crate::update_heap::Task; +use update_heap::UpdateHeap; + +fn get_inv_dependencies_edges(tasks: &Vec<(usize, Vec)>) -> Vec> { + let mut inv_dependencies = vec![vec![]; tasks.len()]; + for i in 0..tasks.len() { + for &v in tasks[i].1.iter() { + inv_dependencies[v].push(i); + } + } + inv_dependencies +} + +fn get_minimum_cost_of_tasks(tasks: &Vec<(usize, Vec)>) -> usize { + let inv_dependencies = get_inv_dependencies_edges(tasks); + + let mut indeg: Vec = vec![0; tasks.len()]; + for v in inv_dependencies.iter() { + for &w in v.iter() { + indeg[w] += 1; + } + } + + let mut heap: UpdateHeap = UpdateHeap::new(); + + for (i, deg) in indeg.iter().enumerate() { + if *deg == 0 { + heap.push(Task::new(i, tasks[i].0)); + } + } + + let mut total_time = 0; + + while !heap.is_empty() { + let task = heap.pop().unwrap(); + + total_time += task.remaining_time; + heap.update(task.remaining_time); + inv_dependencies[task.idx].iter().for_each(|&v| { + indeg[v] -= 1; + if indeg[v] == 0 { + heap.push(Task::new(v, tasks[v].0)); + } + }); + } + + total_time +} + +fn main() { + let mut line = String::new(); + stdin().read_line(&mut line).unwrap(); + let n = line.trim_end().parse::().unwrap(); + line.clear(); + let tasks = (0..n) + .map(|_| { + stdin().read_line(&mut line).unwrap(); + let mut iter = line.split_whitespace(); + let cost = iter.next().unwrap().parse::().unwrap(); + let _ = iter.next(); + let depends = iter + .map(|x| x.parse::().unwrap() - 1) + .collect::>(); + line.clear(); + (cost, depends) + }) + .collect::)>>(); + + println!("{}", get_minimum_cost_of_tasks(&tasks)); +} diff --git a/storage/zeta/rs/completed/25186.rs b/storage/zeta/rs/completed/25186.rs new file mode 100644 index 0000000..5d23027 --- /dev/null +++ b/storage/zeta/rs/completed/25186.rs @@ -0,0 +1,33 @@ +use std::io::stdin; + +fn is_happy(clothes: &Vec) -> bool { + let sum = clothes.iter().sum::(); + if sum == 1 { + return true; + } + let max = clothes.iter().max().unwrap(); + + sum >= max * 2 +} + +fn main() { + let mut lines = stdin().lines(); + lines.next(); + + let clothes: Vec = lines + .next() + .unwrap() + .unwrap() + .split_ascii_whitespace() + .map(|x| x.parse::().unwrap()) + .collect(); + + println!( + "{}", + if is_happy(&clothes) { + "Happy" + } else { + "Unhappy" + } + ) +} diff --git a/storage/zeta/rs/completed/26545.rs b/storage/zeta/rs/completed/26545.rs new file mode 100644 index 0000000..823eff3 --- /dev/null +++ b/storage/zeta/rs/completed/26545.rs @@ -0,0 +1,17 @@ +use std::io::stdin; + +fn main() { + let mut line = String::new(); + stdin().read_line(&mut line).unwrap(); + let n = line.trim().parse::().unwrap(); + println!( + "{}", + (0..n) + .map(|_| { + line.clear(); + stdin().read_line(&mut line).unwrap(); + line.trim_end().parse::().unwrap() + }) + .sum::() + ); +} diff --git a/storage/zeta/rs/completed/27172.rs b/storage/zeta/rs/completed/27172.rs new file mode 100644 index 0000000..7bf2c6a --- /dev/null +++ b/storage/zeta/rs/completed/27172.rs @@ -0,0 +1,62 @@ +use std::io::stdin; + +const X_MAX: usize = 1_000_001; + +/** +get divisor of n excepts n +*/ +fn get_divisors(n: u32) -> Vec { + let mut divisors: Vec = Vec::new(); + divisors.push(1); + for i in 2..=(n as f64).sqrt() as u32 { + if n % i == 0 { + divisors.push(i); + if i != n / i { + divisors.push(n / i); + } + } + } + divisors +} + +fn number_partition_game_result(participants: &Vec) -> Vec { + let mut sorted_participants = participants.clone(); + sorted_participants.sort(); + + let mut scores = vec![0i32; X_MAX]; + let mut exists = vec![false; X_MAX]; + for &p in sorted_participants.iter() { + // N + exists[p as usize] = true; + let divisors = get_divisors(p); // sqrt(X_MAX) + for &d in divisors.iter() { + if exists[d as usize] { + // if p == 1; d == 1; then plus 1 minus 1 consequently zero + scores[d as usize] += 1; + scores[p as usize] -= 1; + } + } + } + + participants.iter().map(|&p| scores[p as usize]).collect() +} + +fn main() { + let mut lines = stdin().lines(); + lines.next(); + let participants: Vec = lines + .next() + .unwrap() + .unwrap() + .split_whitespace() + .map(|x| x.parse::().unwrap()) + .collect(); + println!( + "{}", + number_partition_game_result(&participants) + .into_iter() + .map(|x| x.to_string()) + .collect::>() + .join(" ") + ); +} diff --git a/storage/zeta/rs/completed/30524.rs b/storage/zeta/rs/completed/30524.rs new file mode 100644 index 0000000..a346a0f --- /dev/null +++ b/storage/zeta/rs/completed/30524.rs @@ -0,0 +1,74 @@ +use std::io::{stdin, stdout, BufWriter, Write}; + +fn get_able_pivots(arr: &Vec) -> Vec { + if arr.len() == 1 { + return vec![arr[0]]; + } + + let mut before_max: u32 = 0; + let mut before_min: u32 = u32::MAX; + + let ortho_cumulative_max: Vec = arr + .iter() + .map(|&x| { + if x > before_max { + before_max = x; + } + before_max + }) + .collect(); + + let reverse_cumulative_min: Vec = arr + .iter() + .rev() + .map(|&x| { + if x < before_min { + before_min = x; + } + before_min + }) + .collect::>() + .into_iter() + .rev() + .collect(); + + let mut pivots: Vec = Vec::new(); + + if arr[0] < reverse_cumulative_min[1] { + pivots.push(arr[0]); + } + + for i in 1..arr.len() - 1 { + if ortho_cumulative_max[i - 1] < arr[i] && arr[i] < reverse_cumulative_min[i + 1] { + pivots.push(arr[i]); + } + } + + if arr[arr.len() - 1] > ortho_cumulative_max[arr.len() - 2] { + pivots.push(arr[arr.len() - 1]); + } + pivots +} + +fn main() { + let mut out = BufWriter::new(stdout().lock()); + + let mut line = String::new(); + stdin().read_line(&mut line).unwrap(); + let mut iter = line.split_whitespace(); + let n: usize = iter.next().unwrap().trim_end().parse().unwrap(); + + let arr: Vec = (0..n) + .map(|_| iter.next().unwrap().trim_end().parse().unwrap()) + .collect(); + + (|x: Vec| { + write!(out, "{} ", x.len()).unwrap(); + x + })(get_able_pivots(&arr)) + .into_iter() + .take(100) + .for_each(|x| { + write!(out, "{} ", x).unwrap(); + }); +}