AtCoder Beginner Contest 387 E

https://atcoder.jp/contests/abc387/tasks/abc387_e

9で割れるには各桁の和が9で割り切れればよいです。8で割れるには下3桁が8で割り切れればよいです。ある程度桁数があれば、80…000、140…012などで全て範囲をカバーできます。

// Digit Sum Divisible 2
#![allow(non_snake_case)]


//////////////////// 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 digits(mut n: i32) -> Vec<i32> {
    let mut ds: Vec<i32> = vec![];
    while n > 0 {
        let d = n % 10;
        n /= 10;
        ds.push(d)
    }
    ds
}


//////////////////// process ////////////////////

fn is_good(n: i32) -> bool {
    let ds = digits(n);
    n % ds.into_iter().sum::<i32>() == 0
}

fn F_small(N: i32) -> i32 {
    for n in N..2*N {
        if is_good(n) && is_good(n+1) {
            return n
        }
    }
    -1
}

fn F_large(N: String) -> String {
    let L = N.len();
    if N.as_bytes()[0] == '1' as u8 {
        if N.as_bytes()[1] <= '3' as u8 {
            // 140...00120
            let mut ds: Vec<char> = vec!['0'; L];
            ds[0] = '1';
            ds[1] = '4';
            ds[L-3] = '1';
            ds[L-2] = '2';
            ds.into_iter().collect::<String>()
        }
        else {
            // 200...0024
            let mut ds: Vec<char> = vec!['0'; L];
            ds[0] = '2';
            ds[L-3] = '2';
            ds[L-2] = '4';
            ds.into_iter().collect::<String>()
        }
    }
    else if N.as_bytes()[0] == '2' as u8 {
        // 300...0032
        let mut ds: Vec<char> = vec!['0'; L];
        ds[0] = '3';
        ds[L-3] = '3';
        ds[L-2] = '2';
        ds.into_iter().collect::<String>()
    }
    else if N.as_bytes()[0] == '3' as u8 {
        // 440...0000
        let mut ds: Vec<char> = vec!['0'; L];
        ds[0] = '4';
        ds[1] = '4';
        ds.into_iter().collect::<String>()
    }
    else if N.as_bytes()[0] == '4' as u8 {
        // 620...0000
        let mut ds: Vec<char> = vec!['0'; L];
        ds[0] = '6';
        ds[1] = '2';
        ds.into_iter().collect::<String>()
    }
    else if N.as_bytes()[0] <= '7' as u8 {
        // 80...0000
        let mut ds: Vec<char> = vec!['0'; L];
        ds[0] = '8';
        ds.into_iter().collect::<String>()
    }
    else {
        // 10...00304
        let mut ds: Vec<char> = vec!['0'; L+1];
        ds[0] = '1';
        ds[L-2] = '3';
        ds[L-1] = '0';
        ds[L] = '4';
        ds.into_iter().collect::<String>()
    }
}

fn F(N: String) -> String {
    if N.len() < 5 {
        F_small(N.parse().unwrap()).to_string()
    }
    else {
        F_large(N)
    }
}

fn main() {
    let S: String = read();
    println!("{}", F(S))
}