• 方法一:打表(简单高效)
use std::io;

fn main() {
    let mut s = String::new();
    io::stdin().read_line(&mut s).expect("Failed to read line");
    let n =  match s.trim().parse::<u32>().unwrap() {
        1..=5 => 0,
        6..=27 => 1,
        28..=495 => 2,
        496..=8127 => 3,
        8128..=33_550_335 => 4,
        _ => 5,
    };
    println!("{}",n);
}
  • 方法二:老老实实算出范围内完全数:
    这里设置的上限是10000,如果按照题意所给的500000来会使得此种计算空耗很多时间空间,甚至可能超时,所以只需要规定一个合理的上限即可。
use std::io;

pub fn perfect_list_by_enum(n:u32) -> Vec<u32> {
    let mut v: Vec<u32> = vec![];
    let mut sum = 0u32;
    for i in 2..=n {
        for j in 1..i {
            if i % j == 0 {
                sum += j;
            }
        }
        if sum == i {
            v.push(i);
        }
        sum = 0;
    }
    v
}

fn main() {
    let mut s = String::new();
    io::stdin().read_line(&mut s).expect("Failed To Read Line !");
    let mut n = s.trim().parse::<u32>().unwrap();
    if n > 10000 {
        n = 10000;
    }
    let v = perfect_list_by_enum(n);
    println!("{}",v.len());
}

  • 方法三:欧拉完全数公式(梅森素数):
    对于一个质数n,如果(2^n)-1也是质数,那么((2^n)-1) * 2^(n-1)一定是一个完全数。
use std::io;

pub fn is_prime(n: u32) -> bool {
    let num = (n as f64).sqrt() as u32;
    for i in 2..=num {
        if n % i == 0 {
            return false;
        }
    }
    true
}

fn main() {
    let mut s = String::new();
    io::stdin().read_line(&mut s).expect("Failed To Read Line !");
    let n = s.trim().parse::<u32>().unwrap();
    let mut v = vec![];
    for i in 2..=n {
        match 2u32.checked_pow(i) {
            Some(b) => {
                if is_prime(i) && is_prime(b - 1) {
                    match (b - 1).checked_mul(2u32.pow(i - 1)) {
                        Some(num) => {
                            if num <= n {
                                v.push(num);
                            } else {
                                break;
                            }
                        }
                        None => {
                            break;
                        }
                    }
                }
            }
            None => break,
        }
    }
    println!("{}", v.len());
}