https://atcoder.jp/contests/abc255/tasks/abc255_c
等差数列を構造体にすれば楽になりますが、負数が絡むと不安になりますね。
// ±1 Operation 1 #![allow(non_snake_case)] use std::cmp::min; fn read<T: std::str::FromStr>() -> T { let mut line = String::new(); std::io::stdin().read_line(&mut line).ok(); line.trim().parse().ok().unwrap() } fn read_vec<T: std::str::FromStr>() -> Vec<T> { read::<String>().split_whitespace() .map(|e| e.parse().ok().unwrap()).collect() } fn read_input() -> (i64, i64, i64, i64) { let v = read_vec(); (v[0], v[1], v[2], v[3]) } struct Sequence { A: i64, D: i64, N: i64 } impl Sequence { fn value(&self, i: i64) -> i64 { self.A + self.D * i } fn min(&self) -> i64 { self.value(if self.D >= 0 { 0 } else { self.N - 1 }) } fn max(&self) -> i64 { self.value(if self.D >= 0 { self.N - 1 } else { 0 }) } fn dist(&self, X: i64) -> i64 { if X <= self.min() { self.min() - X } else if X >= self.max() { X - self.max() } else { let i = (X - self.A) / self.D; // 0 <= i < N - 1 let v1 = self.value(i); let v2 = self.value(i + 1); // Dの符号でv1とv2の大小関係が変わる if self.D >= 0 { min(X - v1, v2 - X) } else { min(X - v2, v1 - X) } } } } fn f(v: (i64, i64, i64, i64)) -> i64 { let X = v.0; let A = v.1; let D = v.2; let N = v.3; let S = Sequence { A, D, N }; S.dist(X) } fn main() { let v = read_input(); println!("{}", f(v)) }