【AtCoder】ABC183復習&解説【Rust】
A問題
解法
問題文のReLU関数をそのまま実装する
注意点
負の値が与えられることに注意
ソースコード
use proconio::{fastout, input}; #[fastout] fn main() { input! { x: isize } println!("{}", if x < 0 { 0 } else { x }); }
B問題
解法
ゴールの座標をx軸に対称な場所に取り直し、スタートとゴールを結ぶ直線とx軸との交点を求めることで答えを求めることができる。 よって答えを求めるための1次関数 $y = ax + b$ の定数 $a, b$ は $$ a = \frac{G_y - S_y}{G_x - S_x} $$ $$ b = S_y - a*S_x $$ ただし、 $G_x$ はマイナスをかけ直した値。
これより、yが0のときのxが答えとるので $$ x = - \frac{b}{a} $$
注意点
- 少数の誤差
- 計算時の符号
ソースコード
use proconio::{fastout, input}; #[fastout] fn main() { input! { sx: f64, sy: f64, gx: f64, gy: f64, } let gy = -gy; let a = (gy - sy) / (gx - sx); let b = sy - a * sx; println!("{}", -b / a); }
C問題
解法
すべての経路を探索するには順列全探索を使う。 制約が、 $2 \le N \le 8$ なので $O(N \times N!)$ でも間に合う。
ソースコード
use itertools::Itertools; use proconio::{fastout, input}; #[fastout] fn main() { input! { n: usize, k: usize, t: [[usize; n]; n], } println!( "{}", (1..n) .permutations(n - 1) .filter(|perm| { let mut time = t[0][perm[0]] + t[perm[n - 2]][0]; for i in 0..(n - 2) { time += t[perm[i]][perm[i + 1]]; } time == k }) .count() ); }
D問題
解法
いもす法 を使うことで $O(N + max(T_i))$ で解くことができ、間に合う。 時間は $min(S_i)$ から $max(T_i)$ が扱える配列を用意し記録する。
ソースコード
use proconio::{fastout, input}; #[fastout] fn main() { input! { n: usize, w: usize, stp: [(usize, usize, usize); n] } let mut water = [0; 200000 + 1]; for (s, t, p) in stp { water[s] += p; water[t] -= p; } let mut using = 0; for u in water.iter() { using += u; if using > w { println!("No"); return; } } println!("Yes"); }