题目链接
大意就是有两个参数base,number,求number!在base进制下的数末尾有多少个零。
例如
base:10
,number:10
则:10! = 3628800,末尾有2个零
base:16
,number:16
则:16!=>转换为16进制=>0x130777758000,末尾有三个零
思路
找到base所有素数因子,并且找到包含该素数因子的数量,存为hash表base_hash
找到(1..number+1)找到所有素数因子,以及他们的数量和,存为hash表number_hash
再遍历hash表,找到min(number_hash.get(key)
/base_hash(key)
)
则这个最小值则为我们的anser
代码
激情打码,存在一些冗余
use std::collections::HashMap;
use std::cmp::*;
fn zeroes(base: i32, number: i32) -> i32 {
let prime_tabel: Vec = get_prime_table(base);
let mut divisor_hash: HashMap = HashMap::new();
let divisor_table: Vec = prime_tabel
.iter()
.filter(|&a| base % a == 0)
.cloned()
.collect();
for i in 1..number + 1 {
let mut mut_i = i;
for divisor_num in &divisor_table {
while mut_i % *divisor_num == 0 {
mut_i /= divisor_num;
*divisor_hash.entry(*divisor_num).or_insert(0) += 1;
}
}
}
let mut base_hash:HashMap=HashMap::new();
let mut mut_base=base;
for num in &divisor_table{
while mut_base%num==0{
mut_base/=num;
*base_hash.entry(*num).or_insert(0)+=1;
}
}
let mut answer:i32=i32::max_value();
for (&key,&value) in &divisor_hash{
let base_value=match base_hash.get(&key){
Some(num)=>num,
None=>&0,
};
match value.cmp(&base_value) {
Ordering::Less=>{
answer=0
},
_=>{ answer=min(answer, (value/base_value) as i32)}
}
}
if divisor_hash.is_empty(){
0
}else {
answer
}
}
fn get_prime_table(number: i32) -> Vec {
let mut prime_tabel: Vec = vec![2];
for num in 2..number+1 {
let mut prime_flag = true;
for prime_num in &prime_tabel {
if num % prime_num == 0 {
prime_flag = false;
}
}
if prime_flag {
prime_tabel.push(num);
}
}
prime_tabel
}
大佬的代码
fn zeroes(base: i32, number: i32) -> i32 {
let mut b = base;
(2..base + 1).filter_map(|x| {
let mut n = 0;
while b % x == 0 {
b /= x;
n += 1;
}
if n == 0 {
None
} else {
Some((x, n))
}
}).map(|(p, n)| {
(1..number + 1).fold(0, |acc, x| {
let mut c = 0;
let mut x = x;
while x % p == 0 {
x /= p;
c += 1;
}
acc + c
}) / n
}).min().unwrap_or(0)
}
大佬的代码主要思路和我的差不多,也是先找到base因子及其数目再找到2..number+1的因子和再相除求最小值。
我的代码可以简化的部分有:
- 没必要求prime表,再filter,在求因子的cnt,完全可以一步搞定
- 就是求和那里太罗嗦,不简介
收获就是见识到fold的这个method,还有就是再次被大佬简介的代码震撼。