-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Lance-Drane <ldraneutk@gmail.com>
- Loading branch information
1 parent
53d41ee
commit bb060fa
Showing
1 changed file
with
163 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<u8>, | ||
buf_iter: std::str::SplitAsciiWhitespace<'a>, | ||
} | ||
|
||
impl UnsafeScanner<'_> { | ||
pub fn new<R: std::io::Read>(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::<T>()` 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<T: std::str::FromStr>(&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? | ||
/// | ||
/// <b>Input</b> | ||
/// | ||
/// 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. | ||
/// | ||
/// <b>Output</b> | ||
/// | ||
/// Print one integer: the minimum number of gondolas. | ||
/// | ||
/// <b>Constraints</b> | ||
/// | ||
/// <ul> | ||
/// <li>1 ≤ n ≤ 2 * 10<sup>5</sup></li> | ||
/// <li>1 ≤ x ≤ 10<sup>9</sup></li> | ||
/// <li>1 ≤ p<sub>i</sub> ≤ x</li> | ||
/// </ul> | ||
fn solve<W: std::io::Write>(mut scan: UnsafeScanner, out: &mut W) { | ||
let num_children: u32 = scan.token(); | ||
let max_weight: u32 = scan.token(); | ||
|
||
let mut children: Vec<u32> = (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); | ||
} | ||
} |