AtCoder Beginner Contest 279 D

https://atcoder.jp/contests/abc279/tasks/abc279_d

微分して0になる点から、前後を調べます。ただし、1より小さくなってはいけません。

// Freefall
#![allow(non_snake_case)]


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() -> (u64, u64) {
    let v = read_vec();
    (v[0], v[1])
}

fn time(g: u64, A: u64, B: u64) -> f64 {
    (A as f64) / (g as f64).sqrt() + (B * (g - 1)) as f64
}

fn find_min_time(g0: u64, inc: bool, A: u64, B: u64) -> f64 {
    let t0 = time(g0, A, B);
    if g0 == 1 && !inc {
        return t0
    }
    
    let g = if inc { g0 + 1 } else { g0 - 1 };
    let t1 = time(g, A, B);
    if t0 < t1 {
        t0
    }
    else {
        find_min_time(g, inc, A, B)
    }
}

fn f(A: u64, B: u64) -> f64 {
    let g0: u64 = u64::max(1,
                    ((A as f64) / ((B * 2) as f64)).powf(2.0 / 3.0) as u64);
    return f64::min(find_min_time(g0, true, A, B),
                    find_min_time(g0, false, A, B))
}

fn main() {
    let v = read_input();
    println!("{}", f(v.0, v.1))
}