|
| 1 | +#![allow(unused)] |
| 2 | +// NYAN NYAN |
| 3 | +// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ |
| 4 | +// ░░░░░░░░░░▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄░░░░░░░░░ |
| 5 | +// ░░░░░░░░▄▀░░░░░░░░░░░░▄░░░░░░░▀▄░░░░░░░ |
| 6 | +// ░░░░░░░░█░░▄░░░░▄░░░░░░░░░░░░░░█░░░░░░░ |
| 7 | +// ░░░░░░░░█░░░░░░░░░░░░▄█▄▄░░▄░░░█░▄▄▄░░░ |
| 8 | +// ░▄▄▄▄▄░░█░░░░░░▀░░░░▀█░░▀▄░░░░░█▀▀░██░░ |
| 9 | +// ░██▄▀██▄█░░░▄░░░░░░░██░░░░▀▀▀▀▀░░░░██░░ |
| 10 | +// ░░▀██▄▀██░░░░░░░░▀░██▀░░░░░░░░░░░░░▀██░ |
| 11 | +// ░░░░▀████░▀░░░░▄░░░██░░░▄█░░░░▄░▄█░░██░ |
| 12 | +// ░░░░░░░▀█░░░░▄░░░░░██░░░░▄░░░▄░░▄░░░██░ |
| 13 | +// ░░░░░░░▄█▄░░░░░░░░░░░▀▄░░▀▀▀▀▀▀▀▀░░▄▀░░ |
| 14 | +// ░░░░░░█▀▀█████████▀▀▀▀████████████▀░░░░ |
| 15 | +// ░░░░░░████▀░░███▀░░░░░░▀███░░▀██▀░░░░░░ |
| 16 | +// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ |
| 17 | + |
| 18 | +// CREDIT: |
| 19 | +// read write module: https://github.com/EbTech/rust-algorithms |
| 20 | +//! Generic utility for reading data from standard input, based on [voxl's |
| 21 | +//! stdin wrapper](http://codeforces.com/contest/702/submission/19589375). |
| 22 | +
|
| 23 | +use std::cmp::min; |
| 24 | +use std::collections::HashMap; |
| 25 | +// use std::fs; |
| 26 | +use std::io::Write; |
| 27 | +use std::env; |
| 28 | +// use std::io::{self, BufReader, BufRead}; |
| 29 | +use std::io; |
| 30 | +use std::str; |
| 31 | + |
| 32 | +/// Reads white-space separated tokens one at a time. |
| 33 | +pub struct Scanner<R> { |
| 34 | + reader: R, |
| 35 | + buffer: Vec<String>, |
| 36 | +} |
| 37 | + |
| 38 | +impl<R: io::BufRead> Scanner<R> { |
| 39 | + pub fn new(reader: R) -> Self { |
| 40 | + Self { |
| 41 | + reader, |
| 42 | + buffer: vec![], |
| 43 | + } |
| 44 | + } |
| 45 | + |
| 46 | + /// Use "turbofish" syntax token::<T>() to select data type of next token. |
| 47 | + /// |
| 48 | + /// # Panics |
| 49 | + /// |
| 50 | + /// Panics if there's an I/O error or if the token cannot be parsed as T. |
| 51 | + pub fn token<T: str::FromStr>(&mut self) -> T { |
| 52 | + loop { |
| 53 | + if let Some(token) = self.buffer.pop() { |
| 54 | + return token.parse().ok().expect("Failed parse"); |
| 55 | + } |
| 56 | + let mut input = String::new(); |
| 57 | + self.reader.read_line(&mut input).expect("Failed read"); |
| 58 | + self.buffer = input.split_whitespace().rev().map(String::from).collect(); |
| 59 | + } |
| 60 | + } |
| 61 | +} |
| 62 | + |
| 63 | +/// Same API as Scanner but nearly twice as fast, using horribly unsafe dark arts |
| 64 | +/// **REQUIRES** Rust 1.34 or higher |
| 65 | +pub struct UnsafeScanner<R> { |
| 66 | + reader: R, |
| 67 | + buf_str: Vec<u8>, |
| 68 | + buf_iter: str::SplitAsciiWhitespace<'static>, |
| 69 | +} |
| 70 | + |
| 71 | +impl<R: io::BufRead> UnsafeScanner<R> { |
| 72 | + pub fn new(reader: R) -> Self { |
| 73 | + Self { |
| 74 | + reader, |
| 75 | + buf_str: vec![], |
| 76 | + buf_iter: "".split_ascii_whitespace(), |
| 77 | + } |
| 78 | + } |
| 79 | + |
| 80 | + /// This function should be marked unsafe, but noone has time for that in a |
| 81 | + /// programming contest. Use at your own risk! |
| 82 | + pub fn token<T: str::FromStr>(&mut self) -> T { |
| 83 | + loop { |
| 84 | + if let Some(token) = self.buf_iter.next() { |
| 85 | + return token.parse().ok().expect("Failed parse"); |
| 86 | + } |
| 87 | + self.buf_str.clear(); |
| 88 | + self.reader |
| 89 | + .read_until(b'\n', &mut self.buf_str) |
| 90 | + .expect("Failed read"); |
| 91 | + self.buf_iter = unsafe { |
| 92 | + let slice = str::from_utf8_unchecked(&self.buf_str); |
| 93 | + std::mem::transmute(slice.split_ascii_whitespace()) |
| 94 | + } |
| 95 | + } |
| 96 | + } |
| 97 | +} |
| 98 | + |
| 99 | +pub fn scanner_from_file(filename: &str) -> Scanner<io::BufReader<std::fs::File>> { |
| 100 | + let file = std::fs::File::open(filename).expect("Input file not found"); |
| 101 | + Scanner::new(io::BufReader::new(file)) |
| 102 | +} |
| 103 | + |
| 104 | +pub fn writer_to_file(filename: &str) -> io::BufWriter<std::fs::File> { |
| 105 | + let file = std::fs::File::create(filename).expect("Output file not found"); |
| 106 | + io::BufWriter::new(file) |
| 107 | +} |
| 108 | + |
| 109 | +macro_rules! dbg2 { |
| 110 | + () => { |
| 111 | + eprintln!("[{}:{}]", file!(), line!()); |
| 112 | + }; |
| 113 | + ($val:expr) => { |
| 114 | + // Use of `match` here is intentional because it affects the lifetimes |
| 115 | + // of temporaries - https://stackoverflow.com/a/48732525/1063961 |
| 116 | + match $val { |
| 117 | + tmp => { |
| 118 | + eprintln!("[{}:{}] {} = {:?}", |
| 119 | + file!(), line!(), stringify!($val), &tmp); |
| 120 | + tmp |
| 121 | + } |
| 122 | + } |
| 123 | + }; |
| 124 | + // Trailing comma with single argument is ignored |
| 125 | + ($val:expr,) => { dbg2!($val) }; |
| 126 | + ($($val:expr),+ $(,)?) => { |
| 127 | + ($(dbg2!($val)),+,) |
| 128 | + }; |
| 129 | +} |
| 130 | + |
| 131 | +macro_rules! debug { |
| 132 | + ($e: expr, $DEBUG: ident) => { |
| 133 | + if $DEBUG { |
| 134 | + println!("{} = {}", stringify!($e), $e); |
| 135 | + } |
| 136 | + } |
| 137 | +} |
| 138 | + |
| 139 | +fn main() { |
| 140 | + fn ri32<R: io::BufRead>(scan: &mut UnsafeScanner<R>) -> i32 { |
| 141 | + scan.token::<i32>() |
| 142 | + } |
| 143 | + |
| 144 | + fn rstr<R: io::BufRead>(scan: &mut UnsafeScanner<R>) -> String { |
| 145 | + scan.token::<String>() |
| 146 | + } |
| 147 | + |
| 148 | + fn ru32<R: io::BufRead>(scan: &mut UnsafeScanner<R>) -> u32 { |
| 149 | + scan.token::<u32>() |
| 150 | + } |
| 151 | + |
| 152 | + fn rusize<R: io::BufRead>(scan: &mut UnsafeScanner<R>) -> usize { |
| 153 | + scan.token::<usize>() |
| 154 | + } |
| 155 | + |
| 156 | + fn ri64<R: io::BufRead>(scan: &mut UnsafeScanner<R>) -> i64 { |
| 157 | + scan.token::<i64>() |
| 158 | + } |
| 159 | + |
| 160 | + fn rf64<R: io::BufRead>(scan: &mut UnsafeScanner<R>) -> f64 { |
| 161 | + scan.token::<f64>() |
| 162 | + } |
| 163 | + |
| 164 | + fn rline<R: io::BufRead>(scan: &mut UnsafeScanner<R>){ |
| 165 | + // scan.reader.read_line(buf: &mut String) |
| 166 | + } |
| 167 | + |
| 168 | + // https://stackoverflow.com/questions/41447678/comparison-of-two-floats-in-rust-to-arbitrary-level-of-precision |
| 169 | + fn approx_equal (a:f64,b:f64,dp:u8) -> bool { |
| 170 | + let p:f64 = 10f64.powf(-(dp as f64)); |
| 171 | + |
| 172 | + if (a-b).abs() < p { |
| 173 | + return true; |
| 174 | + } else { |
| 175 | + return false; |
| 176 | + } |
| 177 | + } |
| 178 | + |
| 179 | + fn get_closer(ori: f64, target: f64) -> f64 { |
| 180 | + // if |target - ori| <= 0.5, don't move |
| 181 | + if (target - ori).abs() <= 0.5f64 { |
| 182 | + return ori; |
| 183 | + } |
| 184 | + // otherwise, move closer by one unit |
| 185 | + let plus_ori = ori + 1.0f64; |
| 186 | + let sub_ori = ori - 1.0f64; |
| 187 | + // return which of the two is closer to target |
| 188 | + if (target - plus_ori).abs() < (target - sub_ori).abs() { |
| 189 | + return plus_ori; |
| 190 | + } else { |
| 191 | + return sub_ori; |
| 192 | + } |
| 193 | + } |
| 194 | + |
| 195 | + fn solve<R: io::BufRead, W: io::Write>(scan: &mut UnsafeScanner<R>, out: &mut W) { |
| 196 | + let n = ri32(scan); |
| 197 | + |
| 198 | + // define vec, filled with n integers |
| 199 | + let mut v: Vec<i32> = vec![0; n as usize]; |
| 200 | + |
| 201 | + // read n integers |
| 202 | + for i in 0..n { |
| 203 | + v[i as usize] = ri32(scan); |
| 204 | + } |
| 205 | + |
| 206 | + v.sort(); |
| 207 | + |
| 208 | + let mut ans = 0; |
| 209 | + let mut prev = v[0]; |
| 210 | + // iter over the vec |
| 211 | + for i in 1..n { |
| 212 | + let cur = v[i as usize]; |
| 213 | + if prev != 0 { |
| 214 | + ans += cur - prev; |
| 215 | + prev = 0; |
| 216 | + } else { |
| 217 | + prev = cur; |
| 218 | + } |
| 219 | + } |
| 220 | + |
| 221 | + writeln!(out, "{}", ans); |
| 222 | + |
| 223 | + } |
| 224 | + |
| 225 | + let (stdin, stdout) = (io::stdin(), io::stdout()); |
| 226 | + let mut out = io::BufWriter::new(stdout.lock()); |
| 227 | + let mut scan = UnsafeScanner::new(stdin.lock()); |
| 228 | + solve(&mut scan, &mut out); |
| 229 | +} |
| 230 | + |
0 commit comments