https://atcoder.jp/contests/math-and-algorithm/tasks/math_and_algorithm_bo
積のほうから求める方法もありますが、手間がかかりますね。
// Two Conditions #![allow(non_snake_case)] use std::collections::HashMap; //////////////////// 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() } fn YesNo(b: bool) -> String { return if b { "Yes".to_string() } else { "No".to_string() } } //////////////////// Factors //////////////////// type Factors = Vec<(u32, u32)>; fn div_pow(n: u32, d: u32) -> (u32, u32) { if n % d == 0 { let (e, m) = div_pow(n / d, d); (e + 1, m) } else { (0, n) } } fn factorize(n: u32, p0: u32) -> Factors { if n == 1 { return vec![] } for p in p0.. { if p * p > n { break } if n % p == 0 { let (e, m) = div_pow(n, p); let factors = factorize(m, p + 1); let mut new_factors = vec![(p, e)]; new_factors.extend(&factors); return new_factors } } vec![(n, 1)] } fn value(fs: &Factors) -> u32 { fs.iter().fold(1, |x, (p, e)| x * p.pow(*e)) } fn mul(fs1: &Factors, fs2: &Factors) -> Factors { let mut dic: HashMap<u32, u32> = fs1.iter().map(|&f| f).collect(); for (p, e) in fs2.into_iter() { let entry = dic.entry(*p).or_insert(0); *entry += e } let mut fs: Factors = dic.into_iter().collect(); fs.sort(); fs } fn div(fs1: &Factors, fs2: &Factors) -> Factors { let mut dic: HashMap<u32, u32> = fs1.iter().map(|&f| f).collect(); for (p, e) in fs2.into_iter() { let entry = dic.entry(*p).or_insert(0); *entry -= e; if *entry == 0 { dic.remove(&p); } } let mut fs: Factors = dic.into_iter().collect(); fs.sort(); fs } fn divisors(fs: &Factors) -> Vec<Factors> { if fs.is_empty() { vec![fs.to_vec()] } else if fs.len() == 1 { let (p, e) = fs[0]; (0..e+1).map(|e1| if e1 == 0 { vec![] } else { vec![(p, e1)] }). collect::<Vec<Factors>>() } else { let mid = fs.len() / 2; let fs1 = (0..mid).map(|i| fs[i]).collect::<Factors>(); let fs2 = (mid..fs.len()).map(|i| fs[i]).collect::<Factors>(); let fss1 = divisors(&fs1); let fss2 = divisors(&fs2); let mut fss: Vec<Factors> = Vec::new(); for fs1 in fss1.iter() { for fs2 in fss2.iter() { fss.push(mul(fs1, fs2)) } } fss } } //////////////////// process //////////////////// fn read_input() -> (u32, u32, u32) { let v = read_vec(); let N = v[0]; let X = v[1]; let Y = v[2]; (N, X, Y) } fn divide(fs: &Factors, num_divs: u32, lower: u32) -> Vec<Vec<Factors>> { if num_divs == 1 { let x = value(fs); if x < lower { vec![] } else { vec![vec![fs.to_vec()]] } } else { let mut fsss: Vec<Vec<Factors>> = vec![]; let fss1 = divisors(fs); for fs1 in fss1.into_iter() { let fs2 = div(fs, &fs1); let x = value(&fs1); if x < lower { continue } let fsss2 = divide(&fs2, num_divs-1, x); for mut fss2 in fsss2.into_iter() { let mut fss = vec![fs1.to_vec()]; fss.append(&mut fss2); fsss.push(fss) } } fsss } } fn f(N: u32, X: u32, Y: u32) -> bool { let fs = factorize(Y, 2); let fsss = divide(&fs, 4, 1); let xss: Vec<Vec<u32>> = fsss.into_iter(). map(|fss| fss.iter().map(|fs| value(fs)). collect::<Vec<u32>>()). collect(); xss.into_iter(). any(|xs| xs.iter().all(|x| *x <= N) && xs.iter().sum::<u32>() == X) } fn main() { let (N, X, Y) = read_input(); println!("{}", YesNo(f(N, X, Y))) }