diff --git a/src/bin/search_ferris_wheel.rs b/src/bin/search_ferris_wheel.rs new file mode 100644 index 0000000..9de5387 --- /dev/null +++ b/src/bin/search_ferris_wheel.rs @@ -0,0 +1,163 @@ +// I/O boilerplate // + +pub struct UnsafeScanner<'a> { + // not actually dead code, needed for buf_iter to work + #[allow(dead_code)] + buf_str: Vec, + buf_iter: std::str::SplitAsciiWhitespace<'a>, +} + +impl UnsafeScanner<'_> { + pub fn new(mut reader: R) -> Self { + let mut buf_str = vec![]; + unsafe { + reader.read_to_end(&mut buf_str).unwrap_unchecked(); + } + let buf_iter = unsafe { + let slice = std::str::from_utf8_unchecked(&buf_str); + std::mem::transmute(slice.split_ascii_whitespace()) + }; + // optional memory clear + buf_str.clear(); + + Self { buf_str, buf_iter } + } + + /// Use "turbofish" syntax `token::()` to select data type of next token. + /// + /// # Panics + /// Panics if there's no more tokens or if the token cannot be parsed as T. + pub fn token(&mut self) -> T { + unsafe { + self.buf_iter + .next() + .unwrap_unchecked() + .parse() + .unwrap_unchecked() + } + } +} + +// problem // + +/// There are n children who want to go to a Ferris wheel, and your task is to find a gondola for each child. +/// +/// Each gondola may have one or two children in it, and in addition, the total weight in a gondola may not exceed x. You know the weight of every child. +/// +/// What is the minimum number of gondolas needed for the children? +/// +/// Input +/// +/// The first input line contains two integers n and x: the number of children and the maximum allowed weight. +/// +/// The next line contains n integers p1,p2,...,p_n: the weight of each child. +/// +/// Output +/// +/// Print one integer: the minimum number of gondolas. +/// +/// Constraints +/// +///
    +///
  • 1 ≤ n ≤ 2 * 105
  • +///
  • 1 ≤ x ≤ 109
  • +///
  • 1 ≤ pi ≤ x
  • +///
+fn solve(mut scan: UnsafeScanner, out: &mut W) { + let num_children: u32 = scan.token(); + let max_weight: u32 = scan.token(); + + let mut children: Vec = (0..num_children).map(|_| scan.token()).collect(); + children.sort_unstable(); + + let mut count = 0_u32; + + let mut iter = children.iter(); + while let Some(thin) = iter.next() { + loop { + count += 1; + if let Some(fat) = iter.next_back() { + if thin + fat <= max_weight { + break; + } + } else { + break; + } + } + } + + writeln!(out, "{count}").ok(); +} + +// entrypoints // + +fn main() { + let scan = UnsafeScanner::new(std::io::stdin().lock()); + let mut out = std::io::BufWriter::new(std::io::stdout().lock()); + solve(scan, &mut out); +} + +#[cfg(test)] +mod test { + use super::*; + + fn test(input: &[u8], target: &[u8]) { + let scan = UnsafeScanner::new(input); + let mut out = Vec::with_capacity(target.len()); + solve(scan, &mut out); + + assert_eq!(out, target); + } + + #[test] + fn test_example() { + let input = b"\ +4 10 +7 2 3 9 +"; + let target = b"\ +3 +"; + + test(input, target); + } + + #[test] + fn test_example_2() { + let input = b"\ +1 1 +1 +"; + let target = b"\ +1 +"; + + test(input, target); + } + + #[test] + fn test_example_3() { + let input = b"\ +5 4 +2 2 2 2 2 +"; + let target = b"\ +3 +"; + + test(input, target); + } + + #[test] + fn test_example_4() { + let input = b"\ +5 3 +2 2 2 2 2 +"; + let target = b"\ +5 +"; + + test(input, target); + } +}