1850(rs): solve contest

* “A. To My Critics”
* “B. Ten Words of Wisdom”
* “C. Word on the Paper”
* “D. Balanced Round”
* “E. Cardboard for Pictures”
* “F. We Were Both Children”
* “G. The Morning Star”
* “H. The Third Letter”

Signed-off-by: Matej Focko <me@mfocko.xyz>
This commit is contained in:
Matej Focko 2023-07-24 23:08:43 +02:00
parent 7e4ed33c34
commit 7ec83aafc4
Signed by: mfocko
GPG key ID: 7C47D46246790496
9 changed files with 3157 additions and 0 deletions

1345
1850/index.html Normal file

File diff suppressed because one or more lines are too long

134
1850/src/bin/a.rs Normal file
View file

@ -0,0 +1,134 @@
#![allow(unused_imports)]
use self::input::*;
use self::math::*;
use self::output::*;
fn can_make(mut nums: Vec<i32>) -> bool {
nums.sort();
nums[1] + nums[2] >= 10
}
fn solve(s: &mut Scanner) {
let nums = s.next_vec::<i32>(3);
yesno(can_make(nums));
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn example() {
assert!(can_make(vec![8, 1, 2]));
assert!(!can_make(vec![4, 4, 5]));
assert!(can_make(vec![9, 9, 9]));
assert!(!can_make(vec![0, 0, 0]));
assert!(can_make(vec![8, 5, 3]));
}
}
// region runner
const SINGLE_TEST: bool = false;
fn main() {
let mut s = Scanner::new();
if SINGLE_TEST {
solve(&mut s)
} else {
let n = s.next::<usize>();
for _ in 0..n {
solve(&mut s)
}
}
}
// endregion runner
#[allow(dead_code)]
mod math {
const MOD: i64 = 1_000_000_007;
pub fn add(a: i64, b: i64) -> i64 {
(a + b) % MOD
}
pub fn sub(a: i64, b: i64) -> i64 {
((a - b) % MOD + MOD) % MOD
}
pub fn mul(a: i64, b: i64) -> i64 {
(a * b) % MOD
}
pub fn exp(b: i64, e: i64) -> i64 {
if e == 0 {
return 1;
}
let half = exp(b, e / 2);
if e % 2 == 0 {
return mul(half, half);
}
mul(half, mul(half, b))
}
}
#[allow(dead_code)]
mod output {
pub fn yes() {
println!("YES");
}
pub fn no() {
println!("NO");
}
pub fn yesno(ans: bool) {
println!("{}", if ans { "YES" } else { "NO" });
}
}
#[allow(dead_code)]
mod input {
use std::collections::VecDeque;
use std::io;
use std::str::FromStr;
pub struct Scanner {
buffer: VecDeque<String>,
}
impl Scanner {
pub fn new() -> Scanner {
Scanner {
buffer: VecDeque::new(),
}
}
pub fn next<T: FromStr>(&mut self) -> T {
if self.buffer.is_empty() {
let mut input = String::new();
io::stdin().read_line(&mut input).ok();
for word in input.split_whitespace() {
self.buffer.push_back(word.to_string())
}
}
let front = self.buffer.pop_front().unwrap();
front.parse::<T>().ok().unwrap()
}
pub fn next_vec<T: FromStr>(&mut self, n: usize) -> Vec<T> {
let mut arr = vec![];
for _ in 0..n {
arr.push(self.next::<T>());
}
arr
}
}
}

151
1850/src/bin/b.rs Normal file
View file

@ -0,0 +1,151 @@
#![allow(unused_imports)]
use self::input::*;
use self::math::*;
use self::output::*;
fn find_idx(responses: &[Vec<i32>]) -> usize {
let mut found_idx = responses.len();
let mut found_quality = -1;
for (i, r) in responses.iter().enumerate().filter(|(_, r)| r[0] <= 10) {
if r[1] > found_quality {
found_idx = i + 1;
found_quality = r[1];
}
}
found_idx
}
fn solve(s: &mut Scanner) {
let n = s.next::<usize>();
let input: Vec<Vec<i32>> = (0..n).map(|_| s.next_vec::<i32>(2)).collect();
println!("{}", find_idx(&input));
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn examples() {
assert_eq!(
find_idx(&vec![
vec![7, 2],
vec![12, 5],
vec![9, 3],
vec![9, 4],
vec![10, 1],
]),
4
);
assert_eq!(find_idx(&vec![vec![1, 2], vec![3, 4], vec![5, 6],]), 3);
assert_eq!(find_idx(&vec![vec![1, 43]]), 1);
}
}
// region runner
const SINGLE_TEST: bool = false;
fn main() {
let mut s = Scanner::new();
if SINGLE_TEST {
solve(&mut s)
} else {
let n = s.next::<usize>();
for _ in 0..n {
solve(&mut s)
}
}
}
// endregion runner
#[allow(dead_code)]
mod math {
const MOD: i64 = 1_000_000_007;
pub fn add(a: i64, b: i64) -> i64 {
(a + b) % MOD
}
pub fn sub(a: i64, b: i64) -> i64 {
((a - b) % MOD + MOD) % MOD
}
pub fn mul(a: i64, b: i64) -> i64 {
(a * b) % MOD
}
pub fn exp(b: i64, e: i64) -> i64 {
if e == 0 {
return 1;
}
let half = exp(b, e / 2);
if e % 2 == 0 {
return mul(half, half);
}
mul(half, mul(half, b))
}
}
#[allow(dead_code)]
mod output {
pub fn yes() {
println!("YES");
}
pub fn no() {
println!("NO");
}
pub fn yesno(ans: bool) {
println!("{}", if ans { "YES" } else { "NO" });
}
}
#[allow(dead_code)]
mod input {
use std::collections::VecDeque;
use std::io;
use std::str::FromStr;
pub struct Scanner {
buffer: VecDeque<String>,
}
impl Scanner {
pub fn new() -> Scanner {
Scanner {
buffer: VecDeque::new(),
}
}
pub fn next<T: FromStr>(&mut self) -> T {
if self.buffer.is_empty() {
let mut input = String::new();
io::stdin().read_line(&mut input).ok();
for word in input.split_whitespace() {
self.buffer.push_back(word.to_string())
}
}
let front = self.buffer.pop_front().unwrap();
front.parse::<T>().ok().unwrap()
}
pub fn next_vec<T: FromStr>(&mut self, n: usize) -> Vec<T> {
let mut arr = vec![];
for _ in 0..n {
arr.push(self.next::<T>());
}
arr
}
}
}

210
1850/src/bin/c.rs Normal file
View file

@ -0,0 +1,210 @@
#![allow(unused_imports)]
use self::input::*;
use self::math::*;
use self::output::*;
fn follow(grid: &[Vec<char>], mut y: usize, x: usize) -> String {
let mut found: String = String::new();
while y < grid.len() && grid[y][x] != '.' {
found.push(grid[y][x]);
y += 1;
}
found
}
fn find_word(grid: &[Vec<char>]) -> String {
for (y, x) in (0..8).flat_map(|y| (0..8).map(move |x| (y, x))) {
if grid[y][x] != '.' {
return follow(grid, y, x);
}
}
unreachable!()
}
fn solve(s: &mut Scanner) {
let lines: Vec<Vec<char>> = s
.next_vec::<String>(8)
.into_iter()
.map(|l| l.chars().collect())
.collect();
println!("{}", find_word(&lines));
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn examples() {
assert_eq!(
find_word(
&vec![
"........", "........", "........", "........", "...i....", "........",
"........", "........",
]
.iter()
.map(|s| s.chars().collect::<Vec<char>>())
.collect::<Vec<Vec<char>>>()
),
"i".to_owned()
);
assert_eq!(
find_word(
&vec![
"........", ".l......", ".o......", ".s......", ".t......", "........",
"........", "........",
]
.iter()
.map(|s| s.chars().collect::<Vec<char>>())
.collect::<Vec<Vec<char>>>()
),
"lost".to_owned()
);
assert_eq!(
find_word(
&vec![
"........", "........", "........", "........", "......t.", "......h.",
"......e.", "........",
]
.iter()
.map(|s| s.chars().collect::<Vec<char>>())
.collect::<Vec<Vec<char>>>()
),
"the".to_owned()
);
assert_eq!(
find_word(
&vec![
"........", "........", "........", "........", ".......g", ".......a",
".......m", ".......e",
]
.iter()
.map(|s| s.chars().collect::<Vec<char>>())
.collect::<Vec<Vec<char>>>()
),
"game".to_owned()
);
assert_eq!(
find_word(
&vec![
"a.......", "a.......", "a.......", "a.......", "a.......", "a.......",
"a.......", "a.......",
]
.iter()
.map(|s| s.chars().collect::<Vec<char>>())
.collect::<Vec<Vec<char>>>()
),
"aaaaaaaa".to_owned()
);
}
}
// region runner
const SINGLE_TEST: bool = false;
fn main() {
let mut s = Scanner::new();
if SINGLE_TEST {
solve(&mut s)
} else {
let n = s.next::<usize>();
for _ in 0..n {
solve(&mut s)
}
}
}
// endregion runner
#[allow(dead_code)]
mod math {
const MOD: i64 = 1_000_000_007;
pub fn add(a: i64, b: i64) -> i64 {
(a + b) % MOD
}
pub fn sub(a: i64, b: i64) -> i64 {
((a - b) % MOD + MOD) % MOD
}
pub fn mul(a: i64, b: i64) -> i64 {
(a * b) % MOD
}
pub fn exp(b: i64, e: i64) -> i64 {
if e == 0 {
return 1;
}
let half = exp(b, e / 2);
if e % 2 == 0 {
return mul(half, half);
}
mul(half, mul(half, b))
}
}
#[allow(dead_code)]
mod output {
pub fn yes() {
println!("YES");
}
pub fn no() {
println!("NO");
}
pub fn yesno(ans: bool) {
println!("{}", if ans { "YES" } else { "NO" });
}
}
#[allow(dead_code)]
mod input {
use std::collections::VecDeque;
use std::io;
use std::str::FromStr;
pub struct Scanner {
buffer: VecDeque<String>,
}
impl Scanner {
pub fn new() -> Scanner {
Scanner {
buffer: VecDeque::new(),
}
}
pub fn next<T: FromStr>(&mut self) -> T {
if self.buffer.is_empty() {
let mut input = String::new();
io::stdin().read_line(&mut input).ok();
for word in input.split_whitespace() {
self.buffer.push_back(word.to_string())
}
}
let front = self.buffer.pop_front().unwrap();
front.parse::<T>().ok().unwrap()
}
pub fn next_vec<T: FromStr>(&mut self, n: usize) -> Vec<T> {
let mut arr = vec![];
for _ in 0..n {
arr.push(self.next::<T>());
}
arr
}
}
}

155
1850/src/bin/d.rs Normal file
View file

@ -0,0 +1,155 @@
#![allow(unused_imports)]
// region use
use self::input::*;
use self::math::*;
use self::output::*;
use std::cmp::{max, min};
// endregion use
fn min_to_satisfy(k: i32, mut diffs: Vec<i32>) -> i32 {
diffs.sort();
let mut longest = 0;
let mut current_longest = 1;
for (&x, &y) in diffs.iter().zip(diffs.iter().skip(1)) {
if y - x > k {
longest = max(longest, current_longest);
current_longest = 1;
} else {
current_longest += 1;
}
}
longest = max(longest, current_longest);
diffs.len() as i32 - longest
}
fn solve(s: &mut Scanner) {
let n = s.next::<usize>();
let k = s.next::<i32>();
let diffs = s.next_vec::<i32>(n);
println!("{}", min_to_satisfy(k, diffs));
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn examples() {
assert_eq!(min_to_satisfy(1, vec![1, 2, 4, 5, 6]), 2);
assert_eq!(min_to_satisfy(2, vec![10]), 0);
assert_eq!(min_to_satisfy(3, vec![17, 3, 1, 20, 12, 5, 17, 12]), 5);
assert_eq!(min_to_satisfy(2, vec![2, 4, 6, 8]), 0);
assert_eq!(min_to_satisfy(3, vec![2, 3, 19, 10, 8]), 3);
assert_eq!(min_to_satisfy(4, vec![1, 10, 5]), 1);
assert_eq!(min_to_satisfy(1, vec![8, 3, 1, 4, 5, 10, 7, 3]), 4);
}
}
// region runner
const SINGLE_TEST: bool = false;
fn main() {
let mut s = Scanner::new();
if SINGLE_TEST {
solve(&mut s)
} else {
let n = s.next::<usize>();
for _ in 0..n {
solve(&mut s)
}
}
}
// endregion runner
#[allow(dead_code)]
mod math {
const MOD: i64 = 1_000_000_007;
pub fn add(a: i64, b: i64) -> i64 {
(a + b) % MOD
}
pub fn sub(a: i64, b: i64) -> i64 {
((a - b) % MOD + MOD) % MOD
}
pub fn mul(a: i64, b: i64) -> i64 {
(a * b) % MOD
}
pub fn exp(b: i64, e: i64) -> i64 {
if e == 0 {
return 1;
}
let half = exp(b, e / 2);
if e % 2 == 0 {
return mul(half, half);
}
mul(half, mul(half, b))
}
}
#[allow(dead_code)]
mod output {
pub fn yes() {
println!("YES");
}
pub fn no() {
println!("NO");
}
pub fn yesno(ans: bool) {
println!("{}", if ans { "YES" } else { "NO" });
}
}
#[allow(dead_code)]
mod input {
use std::collections::VecDeque;
use std::io;
use std::str::FromStr;
pub struct Scanner {
buffer: VecDeque<String>,
}
impl Scanner {
pub fn new() -> Scanner {
Scanner {
buffer: VecDeque::new(),
}
}
pub fn next<T: FromStr>(&mut self) -> T {
if self.buffer.is_empty() {
let mut input = String::new();
io::stdin().read_line(&mut input).ok();
for word in input.split_whitespace() {
self.buffer.push_back(word.to_string())
}
}
let front = self.buffer.pop_front().unwrap();
front.parse::<T>().ok().unwrap()
}
pub fn next_vec<T: FromStr>(&mut self, n: usize) -> Vec<T> {
let mut arr = vec![];
for _ in 0..n {
arr.push(self.next::<T>());
}
arr
}
}
}

286
1850/src/bin/e.rs Normal file
View file

@ -0,0 +1,286 @@
#![allow(unused_imports)]
// region use
use self::input::*;
use self::math::*;
use self::output::*;
use std::cmp::{max, min};
// endregion use
fn find_w(covered: i64, sizes: Vec<i64>) -> i64 {
let s: i64 = sizes.iter().sum();
let s_squared: i64 = sizes.iter().map(|s| s * s).sum();
let a = 4 * sizes.len() as i128;
let b = (4 * s) as i128;
let c = (s_squared - covered) as i128;
let d = b * b - 4 * a * c;
((-b + d.isqrt()) / (2 * a)).try_into().unwrap()
}
fn solve(s: &mut Scanner) {
let n = s.next::<usize>();
let c = s.next::<i64>();
let sizes = s.next_vec::<i64>(n);
println!("{}", find_w(c, sizes));
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn examples() {
assert_eq!(find_w(50, vec![3, 2, 1]), 1);
assert_eq!(find_w(100, vec![6]), 2);
assert_eq!(find_w(500, vec![2, 2, 2, 2, 2]), 4);
assert_eq!(find_w(365, vec![3, 4]), 5);
assert_eq!(find_w(469077255466389, vec![10000, 2023]), 7654321);
assert_eq!(
find_w(
635472106413848880,
vec![9181, 4243, 7777, 1859, 2017, 4397, 14, 9390, 2245, 7225]
),
126040443
);
assert_eq!(
find_w(
176345687772781240,
vec![9202, 9407, 9229, 6257, 7743, 5738, 7966]
),
79356352
);
assert_eq!(
find_w(
865563946464579627,
vec![
3654, 5483, 1657, 7571, 1639, 9815, 122, 9468, 3079, 2666, 5498, 4540, 7861,
5384
]
),
124321725
);
assert_eq!(
find_w(
977162053008871403,
vec![
9169, 9520, 9209, 9013, 9300, 9843, 9933, 9454, 9960, 9167, 9964, 9701, 9251,
9404, 9462, 9277, 9661, 9164, 9161
]
),
113385729
);
assert_eq!(
find_w(
886531871815571953,
vec![
2609, 10, 5098, 9591, 949, 8485, 6385, 4586, 1064, 5412, 6564, 8460, 2245,
6552, 5089, 8353, 3803, 3764
]
),
110961227
);
}
}
// region runner
const SINGLE_TEST: bool = false;
fn main() {
let mut s = Scanner::new();
if SINGLE_TEST {
solve(&mut s)
} else {
let n = s.next::<usize>();
for _ in 0..n {
solve(&mut s)
}
}
}
// endregion runner
#[allow(dead_code)]
mod math {
const MOD: i64 = 1_000_000_007;
pub fn add(a: i64, b: i64) -> i64 {
(a + b) % MOD
}
pub fn sub(a: i64, b: i64) -> i64 {
((a - b) % MOD + MOD) % MOD
}
pub fn mul(a: i64, b: i64) -> i64 {
(a * b) % MOD
}
pub fn exp(b: i64, e: i64) -> i64 {
if e == 0 {
return 1;
}
let half = exp(b, e / 2);
if e % 2 == 0 {
return mul(half, half);
}
mul(half, mul(half, b))
}
/// A trait implementing the unsigned bit shifts.
pub trait UnsignedShift {
fn unsigned_shl(self, n: u32) -> Self;
fn unsigned_shr(self, n: u32) -> Self;
}
/// A trait implementing the integer square root.
pub trait ISqrt {
/// Find the integer square root.
///
/// See [Integer_square_root on wikipedia][wiki_article] for more information (and also the
/// source of this algorithm)
///
/// # Panics
///
/// For negative numbers (`i` family) this function will panic on negative input
///
/// [wiki_article]: https://en.wikipedia.org/wiki/Integer_square_root
fn isqrt(&self) -> Self
where
Self: Sized,
{
self.isqrt_checked()
.expect("cannot calculate square root of negative number")
}
/// Find the integer square root, returning `None` if the number is negative (this can never
/// happen for unsigned types).
fn isqrt_checked(&self) -> Option<Self>
where
Self: Sized;
}
macro_rules! math_traits_impl {
($T:ty, $U: ty) => {
impl UnsignedShift for $T {
#[inline]
fn unsigned_shl(self, n: u32) -> Self {
((self as $U) << n) as $T
}
#[inline]
fn unsigned_shr(self, n: u32) -> Self {
((self as $U) >> n) as $T
}
}
impl ISqrt for $T {
#[inline]
fn isqrt_checked(&self) -> Option<Self> {
use core::cmp::Ordering;
match self.cmp(&<$T>::default()) {
// Hopefully this will be stripped for unsigned numbers (impossible condition)
Ordering::Less => return None,
Ordering::Equal => return Some(<$T>::default()),
_ => {}
}
// Compute bit, the largest power of 4 <= n
let max_shift: u32 = <$T>::default().leading_zeros() - 1;
let shift: u32 = (max_shift - self.leading_zeros()) & !1;
let mut bit = <$T>::try_from(1).unwrap().unsigned_shl(shift);
// Algorithm based on the implementation in:
// https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Binary_numeral_system_(base_2)
// Note that result/bit are logically unsigned (even if T is signed).
let mut n = *self;
let mut result = <$T>::default();
while bit != <$T>::default() {
if n >= (result + bit) {
n -= result + bit;
result = result.unsigned_shr(1) + bit;
} else {
result = result.unsigned_shr(1);
}
bit = bit.unsigned_shr(2);
}
Some(result)
}
}
};
}
math_traits_impl!(i8, u8);
math_traits_impl!(u8, u8);
math_traits_impl!(i16, u16);
math_traits_impl!(u16, u16);
math_traits_impl!(i32, u32);
math_traits_impl!(u32, u32);
math_traits_impl!(i64, u64);
math_traits_impl!(u64, u64);
math_traits_impl!(i128, u128);
math_traits_impl!(u128, u128);
math_traits_impl!(isize, usize);
math_traits_impl!(usize, usize);
}
#[allow(dead_code)]
mod output {
pub fn yes() {
println!("YES");
}
pub fn no() {
println!("NO");
}
pub fn yesno(ans: bool) {
println!("{}", if ans { "YES" } else { "NO" });
}
}
#[allow(dead_code)]
mod input {
use std::collections::VecDeque;
use std::io;
use std::str::FromStr;
pub struct Scanner {
buffer: VecDeque<String>,
}
impl Scanner {
pub fn new() -> Scanner {
Scanner {
buffer: VecDeque::new(),
}
}
pub fn next<T: FromStr>(&mut self) -> T {
if self.buffer.is_empty() {
let mut input = String::new();
io::stdin().read_line(&mut input).ok();
for word in input.split_whitespace() {
self.buffer.push_back(word.to_string())
}
}
let front = self.buffer.pop_front().unwrap();
front.parse::<T>().ok().unwrap()
}
pub fn next_vec<T: FromStr>(&mut self, n: usize) -> Vec<T> {
let mut arr = vec![];
for _ in 0..n {
arr.push(self.next::<T>());
}
arr
}
}
}

267
1850/src/bin/f.rs Normal file
View file

@ -0,0 +1,267 @@
#![allow(unused_imports)]
// region use
use self::input::*;
use self::math::*;
use self::output::*;
use std::cmp::{max, min};
use std::collections::HashMap;
// endregion use
fn can_catch(frogs: Vec<i32>) -> usize {
let mut freqs: HashMap<i32, usize> = HashMap::new();
for frog in &frogs {
freqs
.entry(*frog)
.and_modify(|counter| *counter += 1)
.or_insert(1);
}
let max_position = frogs.len();
let mut caught = vec![0; max_position];
for (frog, counter) in freqs.iter() {
for i in (*frog as usize..=max_position).step_by(*frog as usize) {
caught[i - 1] += counter;
}
}
*caught.iter().max().expect("N >= 1")
}
fn solve(s: &mut Scanner) {
let n = s.next::<usize>();
let frogs = s.next_vec::<i32>(n);
println!("{}", can_catch(frogs));
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn example_1() {
assert_eq!(can_catch(vec![1, 2, 3, 4, 5]), 3);
}
#[test]
fn example_2() {
assert_eq!(can_catch(vec![2, 2, 2]), 3);
}
#[test]
fn example_3() {
assert_eq!(can_catch(vec![3, 1, 3, 4, 9, 10]), 3);
}
#[test]
fn example_4() {
assert_eq!(can_catch(vec![1, 3, 2, 4, 2, 3, 7, 8, 5]), 5);
}
#[test]
fn example_5() {
assert_eq!(can_catch(vec![10]), 0);
}
#[test]
fn example_6() {
assert_eq!(can_catch(vec![7, 11, 6, 8, 12, 4, 4, 8]), 4);
}
#[test]
fn example_7() {
assert_eq!(can_catch(vec![9, 11, 9, 12, 1, 7, 2, 5, 8, 10]), 4);
}
#[test]
fn timeout_2() {
assert_eq!(
can_catch(vec![2, 3, 5].into_iter().cycle().take(130000).collect()),
130000
);
}
}
// region runner
const SINGLE_TEST: bool = false;
fn main() {
let mut s = Scanner::new();
if SINGLE_TEST {
solve(&mut s)
} else {
let n = s.next::<usize>();
for _ in 0..n {
solve(&mut s)
}
}
}
// endregion runner
#[allow(dead_code)]
mod math {
const MOD: i64 = 1_000_000_007;
pub fn add(a: i64, b: i64) -> i64 {
(a + b) % MOD
}
pub fn sub(a: i64, b: i64) -> i64 {
((a - b) % MOD + MOD) % MOD
}
pub fn mul(a: i64, b: i64) -> i64 {
(a * b) % MOD
}
pub fn exp(b: i64, e: i64) -> i64 {
if e == 0 {
return 1;
}
let half = exp(b, e / 2);
if e % 2 == 0 {
return mul(half, half);
}
mul(half, mul(half, b))
}
/// A trait implementing the unsigned bit shifts.
pub trait UnsignedShift {
fn unsigned_shl(self, n: u32) -> Self;
fn unsigned_shr(self, n: u32) -> Self;
}
/// A trait implementing the integer square root.
pub trait ISqrt {
fn isqrt(&self) -> Self
where
Self: Sized,
{
self.isqrt_checked()
.expect("cannot calculate square root of negative number")
}
fn isqrt_checked(&self) -> Option<Self>
where
Self: Sized;
}
macro_rules! math_traits_impl {
($T:ty, $U: ty) => {
impl UnsignedShift for $T {
#[inline]
fn unsigned_shl(self, n: u32) -> Self {
((self as $U) << n) as $T
}
#[inline]
fn unsigned_shr(self, n: u32) -> Self {
((self as $U) >> n) as $T
}
}
impl ISqrt for $T {
#[inline]
fn isqrt_checked(&self) -> Option<Self> {
use core::cmp::Ordering;
match self.cmp(&<$T>::default()) {
// Hopefully this will be stripped for unsigned numbers (impossible condition)
Ordering::Less => return None,
Ordering::Equal => return Some(<$T>::default()),
_ => {}
}
// Compute bit, the largest power of 4 <= n
let max_shift: u32 = <$T>::default().leading_zeros() - 1;
let shift: u32 = (max_shift - self.leading_zeros()) & !1;
let mut bit = <$T>::try_from(1).unwrap().unsigned_shl(shift);
// Algorithm based on the implementation in:
// https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Binary_numeral_system_(base_2)
// Note that result/bit are logically unsigned (even if T is signed).
let mut n = *self;
let mut result = <$T>::default();
while bit != <$T>::default() {
if n >= (result + bit) {
n -= result + bit;
result = result.unsigned_shr(1) + bit;
} else {
result = result.unsigned_shr(1);
}
bit = bit.unsigned_shr(2);
}
Some(result)
}
}
};
}
math_traits_impl!(i8, u8);
math_traits_impl!(u8, u8);
math_traits_impl!(i16, u16);
math_traits_impl!(u16, u16);
math_traits_impl!(i32, u32);
math_traits_impl!(u32, u32);
math_traits_impl!(i64, u64);
math_traits_impl!(u64, u64);
math_traits_impl!(i128, u128);
math_traits_impl!(u128, u128);
math_traits_impl!(isize, usize);
math_traits_impl!(usize, usize);
}
#[allow(dead_code)]
mod output {
pub fn yes() {
println!("YES");
}
pub fn no() {
println!("NO");
}
pub fn yesno(ans: bool) {
println!("{}", if ans { "YES" } else { "NO" });
}
}
#[allow(dead_code)]
mod input {
use std::collections::VecDeque;
use std::io;
use std::str::FromStr;
pub struct Scanner {
buffer: VecDeque<String>,
}
impl Scanner {
pub fn new() -> Scanner {
Scanner {
buffer: VecDeque::new(),
}
}
pub fn next<T: FromStr>(&mut self) -> T {
if self.buffer.is_empty() {
let mut input = String::new();
io::stdin().read_line(&mut input).ok();
for word in input.split_whitespace() {
self.buffer.push_back(word.to_string())
}
}
let front = self.buffer.pop_front().unwrap();
front.parse::<T>().ok().unwrap()
}
pub fn next_vec<T: FromStr>(&mut self, n: usize) -> Vec<T> {
let mut arr = vec![];
for _ in 0..n {
arr.push(self.next::<T>());
}
arr
}
}
}

277
1850/src/bin/g.rs Normal file
View file

@ -0,0 +1,277 @@
#![allow(unused_imports)]
// region use
use self::input::*;
use self::math::*;
use self::output::*;
use std::cmp::{max, min};
use std::collections::HashMap;
// endregion use
fn dont_break(points: Vec<(i64, i64)>) -> usize {
let mut x_axis: HashMap<i64, usize> = HashMap::new();
let mut y_axis: HashMap<i64, usize> = HashMap::new();
let mut diag_1: HashMap<i64, usize> = HashMap::new();
let mut diag_2: HashMap<i64, usize> = HashMap::new();
// process the points
for (x, y) in points {
for counter in [
x_axis.entry(x),
y_axis.entry(y),
diag_1.entry(x - y),
diag_2.entry(x + y),
] {
counter.and_modify(|n| *n += 1).or_insert(1);
}
}
// find the final sum
[
x_axis.values(),
y_axis.values(),
diag_1.values(),
diag_2.values(),
]
.map(|counters| counters.map(|n| n * (n - 1)).sum())
.iter()
.sum()
}
fn solve(s: &mut Scanner) {
let n = s.next::<usize>();
let points: Vec<(i64, i64)> = (0..n)
.map(|_| {
let x = s.next::<i64>();
let y = s.next::<i64>();
(x, y)
})
.collect();
println!("{}", dont_break(points));
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn example_1() {
assert_eq!(dont_break(vec![(0, 0), (-1, -1), (1, 1)]), 6);
}
#[test]
fn example_2() {
assert_eq!(dont_break(vec![(4, 5), (5, 7), (6, 9), (10, 13)]), 2);
}
#[test]
fn example_3() {
assert_eq!(
dont_break(vec![
(-1000000000, 1000000000),
(0, 0),
(1000000000, -1000000000)
]),
6
);
}
#[test]
fn example_4() {
assert_eq!(
dont_break(vec![(0, 0), (2, 2), (-1, 5), (-1, 10), (2, 11),]),
8
);
}
#[test]
fn example_5() {
assert_eq!(dont_break(vec![(0, 0), (-1, 2), (1, -2)]), 0);
}
}
// region runner
const SINGLE_TEST: bool = false;
fn main() {
let mut s = Scanner::new();
if SINGLE_TEST {
solve(&mut s)
} else {
let n = s.next::<usize>();
for _ in 0..n {
solve(&mut s)
}
}
}
// endregion runner
#[allow(dead_code)]
mod math {
const MOD: i64 = 1_000_000_007;
pub fn add(a: i64, b: i64) -> i64 {
(a + b) % MOD
}
pub fn sub(a: i64, b: i64) -> i64 {
((a - b) % MOD + MOD) % MOD
}
pub fn mul(a: i64, b: i64) -> i64 {
(a * b) % MOD
}
pub fn exp(b: i64, e: i64) -> i64 {
if e == 0 {
return 1;
}
let half = exp(b, e / 2);
if e % 2 == 0 {
return mul(half, half);
}
mul(half, mul(half, b))
}
/// A trait implementing the unsigned bit shifts.
pub trait UnsignedShift {
fn unsigned_shl(self, n: u32) -> Self;
fn unsigned_shr(self, n: u32) -> Self;
}
/// A trait implementing the integer square root.
pub trait ISqrt {
fn isqrt(&self) -> Self
where
Self: Sized,
{
self.isqrt_checked()
.expect("cannot calculate square root of negative number")
}
fn isqrt_checked(&self) -> Option<Self>
where
Self: Sized;
}
macro_rules! math_traits_impl {
($T:ty, $U: ty) => {
impl UnsignedShift for $T {
#[inline]
fn unsigned_shl(self, n: u32) -> Self {
((self as $U) << n) as $T
}
#[inline]
fn unsigned_shr(self, n: u32) -> Self {
((self as $U) >> n) as $T
}
}
impl ISqrt for $T {
#[inline]
fn isqrt_checked(&self) -> Option<Self> {
use core::cmp::Ordering;
match self.cmp(&<$T>::default()) {
// Hopefully this will be stripped for unsigned numbers (impossible condition)
Ordering::Less => return None,
Ordering::Equal => return Some(<$T>::default()),
_ => {}
}
// Compute bit, the largest power of 4 <= n
let max_shift: u32 = <$T>::default().leading_zeros() - 1;
let shift: u32 = (max_shift - self.leading_zeros()) & !1;
let mut bit = <$T>::try_from(1).unwrap().unsigned_shl(shift);
// Algorithm based on the implementation in:
// https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Binary_numeral_system_(base_2)
// Note that result/bit are logically unsigned (even if T is signed).
let mut n = *self;
let mut result = <$T>::default();
while bit != <$T>::default() {
if n >= (result + bit) {
n -= result + bit;
result = result.unsigned_shr(1) + bit;
} else {
result = result.unsigned_shr(1);
}
bit = bit.unsigned_shr(2);
}
Some(result)
}
}
};
}
math_traits_impl!(i8, u8);
math_traits_impl!(u8, u8);
math_traits_impl!(i16, u16);
math_traits_impl!(u16, u16);
math_traits_impl!(i32, u32);
math_traits_impl!(u32, u32);
math_traits_impl!(i64, u64);
math_traits_impl!(u64, u64);
math_traits_impl!(i128, u128);
math_traits_impl!(u128, u128);
math_traits_impl!(isize, usize);
math_traits_impl!(usize, usize);
}
#[allow(dead_code)]
mod output {
pub fn yes() {
println!("YES");
}
pub fn no() {
println!("NO");
}
pub fn yesno(ans: bool) {
println!("{}", if ans { "YES" } else { "NO" });
}
}
#[allow(dead_code)]
mod input {
use std::collections::VecDeque;
use std::io;
use std::str::FromStr;
pub struct Scanner {
buffer: VecDeque<String>,
}
impl Scanner {
pub fn new() -> Scanner {
Scanner {
buffer: VecDeque::new(),
}
}
pub fn next<T: FromStr>(&mut self) -> T {
if self.buffer.is_empty() {
let mut input = String::new();
io::stdin().read_line(&mut input).ok();
for word in input.split_whitespace() {
self.buffer.push_back(word.to_string())
}
}
let front = self.buffer.pop_front().unwrap();
front.parse::<T>().ok().unwrap()
}
pub fn next_vec<T: FromStr>(&mut self, n: usize) -> Vec<T> {
let mut arr = vec![];
for _ in 0..n {
arr.push(self.next::<T>());
}
arr
}
}
}

332
1850/src/bin/h.rs Normal file
View file

@ -0,0 +1,332 @@
#![allow(unused_imports)]
// region use
use self::input::*;
use self::math::*;
use self::output::*;
use std::cmp::{max, min};
use std::collections::HashMap;
// endregion use
#[derive(Debug, Clone, PartialEq, Eq)]
enum Color {
White,
Gray,
Black,
}
fn dfs(
g: &[Vec<(usize, i64)>],
positions: &mut Vec<i64>,
state: &mut Vec<Color>,
u: usize,
parent: usize,
) -> bool {
state[u] = Color::Gray;
for (v, d) in &g[u] {
if *v == parent {
continue;
}
if state[*v] != Color::White {
if positions[*v] != positions[u] + d {
// we have already assigned the soldier and it doesn't match
return false;
} else {
continue;
}
}
positions[*v] = positions[u] + d;
if !dfs(g, positions, state, *v, u) {
return false;
}
}
state[u] = Color::Black;
true
}
fn can_arrange(n: usize, conditions: Vec<(usize, usize, i64)>) -> bool {
let mut graph = vec![vec![]; n];
// construct graph
for (u, v, d) in conditions {
graph[u - 1].push((v - 1, d));
graph[v - 1].push((u - 1, -d));
}
// run DFS
let mut positions = vec![0; n];
let mut state: Vec<Color> = vec![Color::White; n];
for start in 0..n {
if state[start] != Color::White {
continue;
}
if !dfs(&graph, &mut positions, &mut state, start, n) {
return false;
}
}
true
}
fn solve(s: &mut Scanner) {
let soldiers = s.next::<usize>();
let n = s.next::<usize>();
let conditions: Vec<(usize, usize, i64)> = (0..n)
.map(|_| {
let a = s.next();
let b = s.next();
let d = s.next();
(a, b, d)
})
.collect();
yesno(can_arrange(soldiers, conditions));
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn example_1() {
assert!(can_arrange(5, vec![(1, 2, 2), (2, 3, 4), (4, 2, -6)]));
}
#[test]
fn example_2() {
assert!(!can_arrange(
6,
vec![(1, 2, 2), (2, 3, 4), (4, 2, -6), (5, 4, 4), (3, 5, 100)]
));
}
#[test]
fn example_3() {
assert!(!can_arrange(2, vec![(1, 2, 5), (1, 2, 4)]));
}
#[test]
fn example_4() {
assert!(can_arrange(4, vec![(1, 2, 3)]));
}
#[test]
fn regression_1() {
assert!(can_arrange(
4,
vec![(3, 1, 3), (4, 2, 0), (1, 3, -3), (2, 3, -4)]
))
}
#[test]
fn regression_2() {
assert!(can_arrange(3, vec![(1, 2, 8), (2, 3, -1), (3, 1, -7)]))
}
#[test]
fn regression_3() {
assert!(!can_arrange(
9,
vec![
(1, 2, 536870912),
(2, 3, 536870912),
(3, 4, 536870912),
(4, 5, 536870912),
(5, 6, 536870912),
(6, 7, 536870912),
(7, 8, 536870912),
(8, 9, 536870912),
(1, 9, 0)
]
));
}
}
// region runner
const SINGLE_TEST: bool = false;
fn main() {
let mut s = Scanner::new();
if SINGLE_TEST {
solve(&mut s)
} else {
let n = s.next::<usize>();
for _ in 0..n {
solve(&mut s)
}
}
}
// endregion runner
#[allow(dead_code)]
mod math {
const MOD: i64 = 1_000_000_007;
pub fn add(a: i64, b: i64) -> i64 {
(a + b) % MOD
}
pub fn sub(a: i64, b: i64) -> i64 {
((a - b) % MOD + MOD) % MOD
}
pub fn mul(a: i64, b: i64) -> i64 {
(a * b) % MOD
}
pub fn exp(b: i64, e: i64) -> i64 {
if e == 0 {
return 1;
}
let half = exp(b, e / 2);
if e % 2 == 0 {
return mul(half, half);
}
mul(half, mul(half, b))
}
/// A trait implementing the unsigned bit shifts.
pub trait UnsignedShift {
fn unsigned_shl(self, n: u32) -> Self;
fn unsigned_shr(self, n: u32) -> Self;
}
/// A trait implementing the integer square root.
pub trait ISqrt {
fn isqrt(&self) -> Self
where
Self: Sized,
{
self.isqrt_checked()
.expect("cannot calculate square root of negative number")
}
fn isqrt_checked(&self) -> Option<Self>
where
Self: Sized;
}
macro_rules! math_traits_impl {
($T:ty, $U: ty) => {
impl UnsignedShift for $T {
#[inline]
fn unsigned_shl(self, n: u32) -> Self {
((self as $U) << n) as $T
}
#[inline]
fn unsigned_shr(self, n: u32) -> Self {
((self as $U) >> n) as $T
}
}
impl ISqrt for $T {
#[inline]
fn isqrt_checked(&self) -> Option<Self> {
use core::cmp::Ordering;
match self.cmp(&<$T>::default()) {
// Hopefully this will be stripped for unsigned numbers (impossible condition)
Ordering::Less => return None,
Ordering::Equal => return Some(<$T>::default()),
_ => {}
}
// Compute bit, the largest power of 4 <= n
let max_shift: u32 = <$T>::default().leading_zeros() - 1;
let shift: u32 = (max_shift - self.leading_zeros()) & !1;
let mut bit = <$T>::try_from(1).unwrap().unsigned_shl(shift);
// Algorithm based on the implementation in:
// https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Binary_numeral_system_(base_2)
// Note that result/bit are logically unsigned (even if T is signed).
let mut n = *self;
let mut result = <$T>::default();
while bit != <$T>::default() {
if n >= (result + bit) {
n -= result + bit;
result = result.unsigned_shr(1) + bit;
} else {
result = result.unsigned_shr(1);
}
bit = bit.unsigned_shr(2);
}
Some(result)
}
}
};
}
math_traits_impl!(i8, u8);
math_traits_impl!(u8, u8);
math_traits_impl!(i16, u16);
math_traits_impl!(u16, u16);
math_traits_impl!(i32, u32);
math_traits_impl!(u32, u32);
math_traits_impl!(i64, u64);
math_traits_impl!(u64, u64);
math_traits_impl!(i128, u128);
math_traits_impl!(u128, u128);
math_traits_impl!(isize, usize);
math_traits_impl!(usize, usize);
}
#[allow(dead_code)]
mod output {
pub fn yes() {
println!("YES");
}
pub fn no() {
println!("NO");
}
pub fn yesno(ans: bool) {
println!("{}", if ans { "YES" } else { "NO" });
}
}
#[allow(dead_code)]
mod input {
use std::collections::VecDeque;
use std::io;
use std::str::FromStr;
pub struct Scanner {
buffer: VecDeque<String>,
}
impl Scanner {
pub fn new() -> Scanner {
Scanner {
buffer: VecDeque::new(),
}
}
pub fn next<T: FromStr>(&mut self) -> T {
if self.buffer.is_empty() {
let mut input = String::new();
io::stdin().read_line(&mut input).ok();
for word in input.split_whitespace() {
self.buffer.push_back(word.to_string())
}
}
let front = self.buffer.pop_front().unwrap();
front.parse::<T>().ok().unwrap()
}
pub fn next_vec<T: FromStr>(&mut self, n: usize) -> Vec<T> {
let mut arr = vec![];
for _ in 0..n {
arr.push(self.next::<T>());
}
arr
}
}
}