https://atcoder.jp/contests/math-and-algorithm/tasks/math_and_algorithm_bf
線形計画法ですが、2次元なので、領域が多角形になり、その周辺(というか頂点)をたどっていけばよいです。
ただ、微妙な数値誤差が嫌らしいので、分数を使っています。AtCoderではnum_rationalが使えます。Rationalは成分がisizeであることに注意しなければなりません。
// Linear Programming #![allow(non_snake_case)] use num_rational::Rational; //////////////////// library //////////////////// 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() } //////////////////// process //////////////////// type InEquation = (Rational, Rational); fn read_inequation() -> InEquation { let v: Vec<isize> = read_vec(); (Rational::new(v[0], v[2]), Rational::new(v[1], v[2])) } fn read_input() -> Vec<InEquation> { let N: usize = read(); let ineqs: Vec<InEquation> = (0..N).map(|_| read_inequation()).collect(); return ineqs } fn determinant(ineq1: &InEquation, ineq2: &InEquation) -> Rational { ineq1.0 * ineq2.1 - ineq1.1 * ineq2.0 } type Point = (Rational, Rational); fn intersection(ineq1: &InEquation, ineq2: &InEquation) -> Option<Point> { let D = determinant(ineq1, ineq2); if D == Rational::new(0, 1) { None } else { Some(((ineq2.1 - ineq1.1) / D, (ineq1.0 - ineq2.0) / D)) } } fn f(ineqs: Vec<InEquation>) -> f64 { let mut cur_ineq = ineqs.iter(). min_by_key(|ineq| (ineq.0.recip(), ineq.1.recip())). unwrap(); let mut pt0 = (cur_ineq.0.recip(), Rational::new(0, 1)); let mut pts: Vec<Point> = Vec::new(); pts.push(pt0); loop { let mut v: Vec<(Point, &InEquation)> = Vec::new(); for ineq in ineqs.iter() { if let Some(pt) = intersection(ineq, &cur_ineq) { if Rational::new(0, 1) < pt.0 && pt.0 < pt0.0 { v.push((pt, ineq)) } } } if v.is_empty() { let pt = (Rational::new(0, 1), cur_ineq.1.recip()); pts.push(pt); break } else { let a = v.into_iter().max_by_key(|(pt, _)| pt.0).unwrap(); let pt = a.0; cur_ineq = a.1; pts.push(pt); pt0 = pt } } let z = pts.into_iter().map(|pt| pt.0 + pt.1).max().unwrap(); (*z.numer() as f64) / (*z.denom() as f64) } fn main() { let ineqs = read_input(); println!("{}", f(ineqs)) }