1use std::cmp::Reverse;
4use std::collections::{BTreeSet, BinaryHeap, HashMap};
5
6struct Sol407;
8
9impl Sol407 {
10 pub fn trap_rain_water(height_map: Vec<Vec<i32>>) -> i32 {
11 let (rows, cols) = (height_map.len(), height_map[0].len());
12
13 #[derive(Debug, PartialEq, Eq, Ord, PartialOrd)]
14 struct Cell {
15 height: i32,
16 r: i32,
17 c: i32,
18 }
19
20 let mut visited = vec![vec![false; cols]; rows];
21
22 use std::cmp::Reverse;
23 use std::collections::BinaryHeap;
24
25 let mut pq = BinaryHeap::new();
26 for r in 0..rows {
27 for c in 0..cols {
28 if r == 0 || c == 0 || r == rows - 1 || c == cols - 1 {
29 pq.push(Reverse(Cell {
30 height: height_map[r][c],
31 r: r as i32,
32 c: c as i32,
33 }));
34
35 visited[r][c] = true;
36 }
37 }
38 }
39
40 println!(" -> {pq:?}");
41 println!(" -> {visited:?}");
42
43 let mut trap_water = 0;
44 let dirs = [-1, 0, 1, 0, -1];
45
46 while let Some(Reverse(cell)) = pq.pop() {
47 println!(" -> {cell:?}");
48
49 (0..4).for_each(|i| {
50 let (r, c) = (cell.r + dirs[i], cell.c + dirs[i + 1]);
51 if 0 <= r
52 && r < rows as i32
53 && 0 <= c
54 && c < cols as i32
55 && !visited[r as usize][c as usize]
56 {
57 visited[r as usize][c as usize] = true;
58
59 let h = height_map[r as usize][c as usize];
60 if h < cell.height {
61 trap_water += cell.height - h;
62 }
63
64 pq.push(Reverse(Cell {
65 height: h.max(cell.height),
66 r,
67 c,
68 }));
69 }
70 });
71 }
72
73 println!(" -> {visited:?}");
74
75 trap_water
76 }
77}
78
79struct Sol778 {}
81
82impl Sol778 {
83 pub fn swim_in_water(mut grid: Vec<Vec<i32>>) -> i32 {
84 use std::cmp::Reverse;
85 use std::collections::BinaryHeap;
86
87 let mut pq = BinaryHeap::new();
88 pq.push((Reverse(grid[0][0]), 0, 0));
89
90 let mut t = 0;
91 while let Some((Reverse(height), r, c)) = pq.pop() {
92 println!("-> {:?}", (height, r, c));
93
94 if r + 1 == grid.len() && c + 1 == grid[r].len() {
95 println!("-> {pq:?}");
96
97 return t.max(height);
98 }
99
100 t = t.max(height);
101
102 for (dr, dc) in [(1, 0), (-1, 0), (0, 1), (0, -1)] {
103 let (r, c) = (r.wrapping_add_signed(dr), c.wrapping_add_signed(dc));
104 if r < grid.len() && c < grid[r].len() && grid[r][c] != -1 {
105 pq.push((Reverse(grid[r][c]), r, c));
106 grid[r][c] = -1;
107 }
108 }
109 }
110
111 -1
112 }
113}
114
115struct Sol1046 {}
117
118impl Sol1046 {
119 pub fn last_stone_weight(stones: Vec<i32>) -> i32 {
120 use std::collections::BinaryHeap;
121
122 let mut hvs = BinaryHeap::new();
123 for stone in stones {
124 hvs.push(stone);
125 }
126
127 while hvs.len() > 1 {
128 let w1 = hvs.pop().unwrap();
129 let w2 = hvs.pop().unwrap();
130 if w1 > w2 {
131 hvs.push(w1 - w2);
132 }
133 }
134
135 hvs.pop().unwrap_or(0)
136 }
137}
138
139struct Sol1792 {}
141
142impl Sol1792 {
143 pub fn max_average_ratio(classes: Vec<Vec<i32>>, extra_students: i32) -> f64 {
144 use std::cmp::Ordering;
145 use std::collections::BinaryHeap;
146
147 #[derive(Debug)]
148 struct Class {
149 gain: f64, pass: i32,
151 total: i32,
152 }
153
154 impl Ord for Class {
155 fn cmp(&self, other: &Self) -> Ordering {
156 self.gain.partial_cmp(&other.gain).unwrap()
157 }
158 }
159 impl PartialOrd for Class {
160 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
161 Some(self.cmp(other))
162 }
163 }
164
165 impl Eq for Class {}
166 impl PartialEq for Class {
167 fn eq(&self, other: &Self) -> bool {
168 self.pass == other.pass && self.total == other.total
169 }
170 }
171
172 fn gain(pass: i32, total: i32) -> f64 {
173 (pass + 1) as f64 / (total + 1) as f64 - pass as f64 / total as f64
174 }
175
176 let mut pq: BinaryHeap<Class> = classes
177 .iter()
178 .map(|v| (v[0], v[1]))
179 .map(|(pass, total)| Class {
180 gain: gain(pass, total),
181 pass,
182 total,
183 })
184 .collect();
185 println!("-> {pq:?}");
186
187 for _ in 0..extra_students {
188 if let Some(Class {
189 gain: _,
190 pass,
191 total,
192 }) = pq.pop()
193 {
194 pq.push(Class {
195 gain: gain(pass + 1, total + 1),
196 pass: pass + 1,
197 total: total + 1,
198 });
199 }
200 }
201 println!("-> {pq:?}");
202
203 pq.iter()
204 .map(
205 |&Class {
206 gain: _,
207 pass,
208 total,
209 }| pass as f64 / total as f64,
210 )
211 .sum::<f64>()
212 / pq.len() as f64
213 }
214}
215
216#[derive(Debug)]
218struct MovieRentingSystem1912 {
219 prices: std::collections::HashMap<(i32, i32), i32>, movies: std::collections::HashMap<i32, std::collections::BTreeSet<(i32, i32)>>, pq: std::collections::BTreeSet<(i32, i32, i32)>, }
223
224impl MovieRentingSystem1912 {
225 #[allow(unused_variables)]
228 fn new(n: i32, entries: Vec<Vec<i32>>) -> Self {
229 MovieRentingSystem1912 {
230 prices: entries.iter().map(|v| ((v[0], v[1]), v[2])).collect(),
231 movies: entries.iter().map(|v| (v[0], v[1], v[2])).fold(
232 HashMap::new(),
233 |mut movies, (shop, movie, price)| {
234 movies
235 .entry(movie)
236 .or_insert_with(BTreeSet::new)
237 .insert((price, shop));
238
239 movies
240 },
241 ),
242 pq: BTreeSet::new(),
243 }
244 }
245
246 fn search(&self, movie: i32) -> Vec<i32> {
247 self.movies.get(&movie).map_or(vec![], |movies| {
248 movies.iter().take(5).map(|&(_, shop)| shop).collect()
249 })
250 }
251
252 fn rent(&mut self, shop: i32, movie: i32) {
253 if let Some(&price) = self.prices.get(&(shop, movie)) {
254 self.movies
255 .get_mut(&movie)
256 .map(|movies| movies.remove(&(price, shop)));
257
258 self.pq.insert((price, shop, movie));
259 }
260 }
261
262 fn drop(&mut self, shop: i32, movie: i32) {
263 if let Some(&price) = self.prices.get(&(shop, movie)) {
264 self.movies
265 .get_mut(&movie)
266 .map(|movies| movies.insert((price, shop)));
267
268 self.pq.remove(&(price, shop, movie));
269 }
270 }
271
272 fn report(&self) -> Vec<Vec<i32>> {
273 self.pq
274 .iter()
275 .take(5)
276 .map(|&(_, shop, movie)| vec![shop, movie])
277 .collect()
278 }
279}
280
281struct Sol2231 {}
283
284impl Sol2231 {
285 pub fn largest_integer(mut num: i32) -> i32 {
286 use std::collections::BinaryHeap;
287
288 let mut qs = [BinaryHeap::new(), BinaryHeap::new()];
289 let mut pars = vec![];
290
291 while num > 0 {
292 let parity = (num % 10) as usize & 1;
293
294 pars.push(parity);
295 qs[parity].push(num % 10);
296
297 num /= 10;
298 }
299 println!("-> {qs:?}");
300
301 let mut x = 0;
302 for &parity in pars.iter().rev() {
303 if let Some(digit) = qs[parity].pop() {
304 x = 10 * x + digit;
305 }
306 }
307
308 x
309 }
310}
311
312#[derive(Debug)]
314struct FoodRatings2353 {
315 data: HashMap<String, BinaryHeap<(i32, Reverse<String>)>>,
316 f_cuisine: HashMap<String, String>,
317 f_rating: HashMap<String, i32>,
318}
319
320impl FoodRatings2353 {
321 fn new(foods: Vec<String>, cuisines: Vec<String>, ratings: Vec<i32>) -> Self {
322 FoodRatings2353 {
323 data: cuisines
324 .iter()
325 .enumerate()
326 .fold(HashMap::new(), |mut data, (i, cuisine)| {
327 data.entry(cuisine.to_string())
328 .and_modify(|pq| pq.push((ratings[i], Reverse(foods[i].clone()))))
329 .or_insert(BinaryHeap::from([(ratings[i], Reverse(foods[i].clone()))]));
330
331 data
332 }),
333 f_cuisine: foods
334 .iter()
335 .enumerate()
336 .map(|(i, food)| (food.clone(), cuisines[i].clone()))
337 .collect(),
338 f_rating: foods
339 .iter()
340 .zip(ratings.iter())
341 .map(|(food, &rating)| (food.clone(), rating))
342 .collect(),
343 }
344 }
345
346 fn change_rating(&mut self, food: String, new_rating: i32) {
347 if let Some(pq) = self.data.get_mut(&self.f_cuisine[&food]) {
348 pq.push((new_rating, Reverse(food.to_string())));
349 self.f_rating.insert(food.to_string(), new_rating);
350 }
351 }
352
353 fn highest_rated(&mut self, cuisine: String) -> String {
354 if let Some(pq) = self.data.get_mut(&cuisine) {
355 while let Some((rating, Reverse(food))) = pq.peek() {
356 if *rating == self.f_rating[food] {
357 return food.clone();
358 } else {
359 pq.pop(); }
361 }
362 }
363
364 panic!()
365 }
366}
367
368struct Sol3066;
370
371impl Sol3066 {
372 pub fn min_operations(nums: Vec<i32>, k: i32) -> i32 {
373 use std::cmp::Reverse;
374 use std::collections::BinaryHeap;
375
376 let mut pq = BinaryHeap::new();
377 for n in nums {
378 pq.push(Reverse(n as usize));
379 }
380
381 let mut ops = 0;
382 while let Some(&Reverse(x)) = pq.peek() {
383 if x < k as usize {
384 pq.pop();
385 if let Some(Reverse(y)) = pq.pop() {
386 pq.push(Reverse(x.min(y) * 2 + x.max(y)));
387 }
388 } else {
389 break;
390 }
391 ops += 1;
392 }
393
394 println!("-> {pq:?}");
395
396 ops
397 }
398}
399
400struct Sol3147 {}
402
403impl Sol3147 {
404 pub fn maximum_energy(energy: Vec<i32>, k: i32) -> i32 {
405 (0..k as usize).fold(i32::MIN, |mut e_max, start| {
406 let mut e_sum = 0;
407 for e in energy.iter().skip(start).step_by(k as usize).rev() {
408 e_sum += e;
409 e_max = e_max.max(e_sum);
410 }
411
412 e_max
413 })
414 }
415}
416
417struct Sol3362;
419
420impl Sol3362 {
421 pub fn max_removal(nums: Vec<i32>, queries: Vec<Vec<i32>>) -> i32 {
424 use std::collections::BinaryHeap;
425
426 #[derive(Debug)]
427 struct Fenwick {
428 tree: Vec<i32>,
429 }
430
431 impl Fenwick {
432 fn new(size: usize) -> Self {
433 Fenwick {
434 tree: vec![0; size + 1],
435 }
436 }
437
438 fn update(&mut self, mut i: usize, diff: i32) {
439 while i < self.tree.len() {
440 self.tree[i] += diff;
441 i += i & (!i + 1);
442 }
443 }
444
445 fn query(&self, mut i: usize) -> i32 {
446 let mut r = 0;
447 while i > 0 {
448 r += self.tree[i];
449 i -= i & (!i + 1);
450 }
451 r
452 }
453 }
454
455 let mut fwt = Fenwick::new(nums.len() + 2);
456 for query in &queries {
457 fwt.update(query[0] as usize + 1, 1);
458 fwt.update(query[1] as usize + 1 + 1, -1);
459 }
460 println!(
461 "-> {:?} {fwt:?}",
462 (1..=nums.len()).map(|i| fwt.query(i)).collect::<Vec<_>>()
463 );
464
465 let mut queries = queries;
466 queries.sort_by(|q1, q2| {
467 if q1[0] == q2[0] {
468 q2[1].cmp(&q1[1])
469 } else {
470 q1[0].cmp(&q2[0])
471 }
472 });
473 println!("-> {queries:?}");
474
475 let mut pq = BinaryHeap::new();
476
477 let (mut diff, mut diffs) = (0, vec![0; nums.len() + 1]);
478 let mut q = 0;
479 for (i, &n) in nums.iter().enumerate() {
480 diff += diffs[i];
481
482 while q < queries.len() && queries[q][0] as usize == i {
483 pq.push(queries[q][1]);
484 q += 1;
485 }
486
487 while diff < n {
488 match pq.peek() {
489 Some(&right) if right >= i as i32 => {
490 diff += 1;
491 diffs[right as usize + 1] -= 1;
492
493 pq.pop();
494 }
495 _ => break,
496 }
497 }
498
499 if diff < n {
500 return -1;
501 }
502 }
503
504 pq.len() as _
505 }
506}
507
508#[derive(Debug)]
510struct TaskManager3408 {
511 oset: BTreeSet<(i32, i32, i32)>, task: HashMap<i32, (i32, i32)>, }
514
515impl TaskManager3408 {
516 fn new(tasks: Vec<Vec<i32>>) -> Self {
517 TaskManager3408 {
518 oset: tasks
519 .iter()
520 .map(|task| (task[2], task[1], task[0]))
521 .collect(),
522 task: tasks
523 .iter()
524 .map(|task| (task[1], (task[0], task[2])))
525 .collect(),
526 }
527 }
528
529 fn add(&mut self, user_id: i32, task_id: i32, priority: i32) {
530 self.oset.insert((priority, task_id, user_id));
531 self.task.insert(task_id, (user_id, priority));
532 }
533
534 fn edit(&mut self, task_id: i32, new_priority: i32) {
535 if let Some((user, priority)) = self.task.get_mut(&task_id)
536 && self.oset.take(&(*priority, task_id, *user)).is_some()
537 {
538 self.oset.insert((new_priority, task_id, *user));
539 *priority = new_priority;
540 }
541 }
542
543 fn rmv(&mut self, task_id: i32) {
544 if let Some((user, priority)) = self.task.remove(&task_id) {
545 self.oset.take(&(priority, task_id, user));
546 }
547 }
548
549 fn exec_top(&mut self) -> i32 {
550 if let Some((_, task, user)) = self.oset.pop_last() {
551 self.task.remove(&task);
552 return user;
553 }
554 -1
555 }
556}
557
558#[cfg(test)]
559mod tests;