use std::collections::{HashMap, HashSet, VecDeque}; fn distance(a: (i64, i64), b: (i64, i64)) -> i64 { let (x1, y1) = a; let (x2, y2) = b; (x1 - x2).pow(2) + (y1 - y2).pow(2) } struct Graph { edges: HashMap>, } impl Graph { fn new(bombs: &[Vec]) -> Self { let mut edges = HashMap::new(); for (i, bomb) in bombs.iter().enumerate() { edges.insert(i, HashSet::new()); let neighbours = edges.get_mut(&i).unwrap(); let (x, y, r) = (bomb[0], bomb[1], bomb[2]); let rr = (r as i64).pow(2); for j in 0..bombs.len() { if i == j { continue; } let (x1, y1) = (bombs[j][0], bombs[j][1]); if distance((x as i64, y as i64), (x1 as i64, y1 as i64)) <= rr { neighbours.insert(j); } } } Self { edges } } fn bfs(&self, mut visited: Vec, u0: usize) -> i32 { let mut found = 0; let mut q = VecDeque::new(); q.push_back(u0); visited[u0] = true; while let Some(u) = q.pop_front() { found += 1; for &v in self.edges.get(&u).unwrap_or(&HashSet::new()) { if !visited[v] { q.push_back(v); visited[v] = true; } } } found } } struct Solution {} impl Solution { pub fn maximum_detonation(bombs: Vec>) -> i32 { let graph = Graph::new(&bombs); let visited = vec![false; bombs.len()]; (0..bombs.len()) .map(|u| graph.bfs(visited.clone(), u)) .max() .unwrap_or(0) } } fn main() {} #[cfg(test)] mod tests { use super::*; #[test] fn example_1() { assert_eq!( Solution::maximum_detonation(vec![vec![2, 1, 3], vec![6, 1, 4]]), 2 ); } #[test] fn example_2() { assert_eq!( Solution::maximum_detonation(vec![vec![1, 1, 5], vec![10, 10, 5]]), 1 ); } #[test] fn example_3() { assert_eq!( Solution::maximum_detonation(vec![ vec![1, 2, 3], vec![2, 3, 1], vec![3, 4, 2], vec![4, 5, 3], vec![5, 6, 4] ]), 5 ); } #[test] fn regression_1() { assert_eq!( Solution::maximum_detonation(vec![vec![1, 1, 100000], vec![100000, 100000, 1]]), 1 ); } }