complete 2056.rs 16724.rs 17143.rs 25186.rs 26545.rs 27172.rs 30524.rs

This commit is contained in:
2025-07-05 11:59:23 +09:00
parent 77d1aa106b
commit 477c09c46a
7 changed files with 734 additions and 0 deletions

View File

@@ -0,0 +1,99 @@
use std::io::stdin;
fn interpret_map(size: (usize, usize), map_strings: &Vec<String>) -> Vec<usize> {
let mut edges: Vec<usize> = 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<usize>, 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<usize>, 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>) -> usize {
let mut parents = (0..size.0 * size.1).collect::<Vec<_>>();
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::<usize>().unwrap();
let m = iter.next().unwrap().parse::<usize>().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::<Vec<_>>();
let edges = interpret_map((n, m), &map_strings);
println!("{}", get_count_of_safezone((n, m), &edges));
}

View File

@@ -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<u8> for Direction {
type Error = ();
fn try_from(value: u8) -> Result<Self, Self::Error> {
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<Self, Self::Err> {
Direction::try_from(value.parse::<u8>().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<Shark>) -> u32 {
let mut map: Vec<usize> = 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<usize>,
sharks: &mut Vec<Shark>,
exists: &mut Vec<bool>,
) {
// 이동
let move_record = sharks
.iter()
.enumerate()
.filter(|&(i, _shark)| exists[i])
.map(|(i, shark)| (i, shark.pos, move_result(size, shark)))
.collect::<Vec<_>>();
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::<usize>().unwrap() - 1,
iter.next().unwrap().parse::<usize>().unwrap() - 1,
iter.next().unwrap().parse::<u32>().unwrap(), // speed
iter.next().unwrap().parse::<Direction>().unwrap(), // dir
iter.next().unwrap().parse::<u32>().unwrap(), // size
)
})
.collect::<Vec<_>>();
println!("{}", get_total_size_sharks_caught(size, sharks));
}

View File

@@ -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<Self> for Task {
fn eq(&self, other: &Self) -> bool {
self.remaining_time == other.remaining_time
}
}
impl PartialOrd<Self> for Task {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.remaining_time.partial_cmp(&other.remaining_time)
}
}
pub struct UpdateHeap {
data: Vec<Task>,
}
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<Task> {
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<usize>)>) -> Vec<Vec<usize>> {
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>)>) -> usize {
let inv_dependencies = get_inv_dependencies_edges(tasks);
let mut indeg: Vec<usize> = 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::<usize>().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::<usize>().unwrap();
let _ = iter.next();
let depends = iter
.map(|x| x.parse::<usize>().unwrap() - 1)
.collect::<Vec<usize>>();
line.clear();
(cost, depends)
})
.collect::<Vec<(usize, Vec<usize>)>>();
println!("{}", get_minimum_cost_of_tasks(&tasks));
}

View File

@@ -0,0 +1,33 @@
use std::io::stdin;
fn is_happy(clothes: &Vec<u64>) -> bool {
let sum = clothes.iter().sum::<u64>();
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<u64> = lines
.next()
.unwrap()
.unwrap()
.split_ascii_whitespace()
.map(|x| x.parse::<u64>().unwrap())
.collect();
println!(
"{}",
if is_happy(&clothes) {
"Happy"
} else {
"Unhappy"
}
)
}

View File

@@ -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::<usize>().unwrap();
println!(
"{}",
(0..n)
.map(|_| {
line.clear();
stdin().read_line(&mut line).unwrap();
line.trim_end().parse::<i32>().unwrap()
})
.sum::<i32>()
);
}

View File

@@ -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<u32> {
let mut divisors: Vec<u32> = 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<u32>) -> Vec<i32> {
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<u32> = lines
.next()
.unwrap()
.unwrap()
.split_whitespace()
.map(|x| x.parse::<u32>().unwrap())
.collect();
println!(
"{}",
number_partition_game_result(&participants)
.into_iter()
.map(|x| x.to_string())
.collect::<Vec<String>>()
.join(" ")
);
}

View File

@@ -0,0 +1,74 @@
use std::io::{stdin, stdout, BufWriter, Write};
fn get_able_pivots(arr: &Vec<u32>) -> Vec<u32> {
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<u32> = arr
.iter()
.map(|&x| {
if x > before_max {
before_max = x;
}
before_max
})
.collect();
let reverse_cumulative_min: Vec<u32> = arr
.iter()
.rev()
.map(|&x| {
if x < before_min {
before_min = x;
}
before_min
})
.collect::<Vec<u32>>()
.into_iter()
.rev()
.collect();
let mut pivots: Vec<u32> = 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<u32> = (0..n)
.map(|_| iter.next().unwrap().trim_end().parse().unwrap())
.collect();
(|x: Vec<u32>| {
write!(out, "{} ", x.len()).unwrap();
x
})(get_able_pivots(&arr))
.into_iter()
.take(100)
.for_each(|x| {
write!(out, "{} ", x).unwrap();
});
}