校招算法笔面试 | 华为机试-完全数计算

题目## 题目

题目链接

解题思路

  1. 完全数的定义:一个数等于它的所有真因子(除了自身以外的约数)之和

    • 例如:28的真因子有1,2,4,7,14,且1+2+4+7+14=28
  2. 实现思路:

    • 遍历1到 n n n 的每个数
    • 对每个数找出其所有真因子
    • 判断真因子之和是否等于该数本身
    • 统计满足条件的数的个数
  3. 优化:

    • 只需要遍历到 n \sqrt{n} n 就可以找到所有因子
    • 已知的完全数很少,可以直接判断

代码

#include <iostream>
using namespace std;

bool isPerfectNumber(int num) {
    if (num <= 1) return false;
    int sum = 1;  // 1总是因子
    // 只需要遍历到sqrt(num)
    for (int i = 2; i * i <= num; i++) {
        if (num % i == 0) {
            sum += i;
            if (i * i != num) {  // 避免平方数重复计算
                sum += num / i;
            }
        }
    }
    return sum == num;
}

int main() {
    int n;
    while (cin >> n) {
        int count = 0;
        for (int i = 1; i <= n; i++) {
            if (isPerfectNumber(i)) {
                count++;
            }
        }
        cout << count << endl;
    }
    return 0;
}
import java.util.Scanner;

public class Main {
    private static boolean isPerfectNumber(int num) {
        if (num <= 1) return false;
        int sum = 1;  // 1总是因子
        // 只需要遍历到sqrt(num)
        for (int i = 2; i * i <= num; i++) {
            if (num % i == 0) {
                sum += i;
                if (i * i != num) {  // 避免平方数重复计算
                    sum += num / i;
                }
            }
        }
        return sum == num;
    }
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            int n = sc.nextInt();
            int count = 0;
            for (int i = 1; i <= n; i++) {
                if (isPerfectNumber(i)) {
                    count++;
                }
            }
            System.out.println(count);
        }
    }
}
def is_perfect_number(num):
    if num <= 1:
        return False
    sum_factors = 1  # 1总是因子
    # 只需要遍历到sqrt(num)
    i = 2
    while i * i <= num:
        if num % i == 0:
            sum_factors += i
            if i * i != num:  # 避免平方数重复计算
                sum_factors += num // i
        i += 1
    return sum_factors == num

while True:
    try:
        n = int(input())
        count = 0
        for i in range(1, n + 1):
            if is_perfect_number(i):
                count += 1
        print(count)
    except EOFError:
        break

算法及复杂度

  • 算法:试除法找因子
  • 时间复杂度: O ( n n ) \mathcal{O}(n\sqrt{n}) O(nn ) - 需要遍历1到n的每个数,每个数需要 O ( n ) \mathcal{O}(\sqrt{n}) O(n )的时间找因子
  • 空间复杂度: O ( 1 ) \mathcal{O}(1) O(1) - 只使用了常数额外空间

题目链接

解题思路

这是一个简单的字符串逆序问题,需要将输入的字符串反转后输出。需要注意的是输入的字符串可能包含空格。

关键点

  1. 数据范围:

    • 字符串长度: 1 ≤ l e n ( s t r ) ≤ 10000 1 \leq len(str) \leq 10000 1len(str)10000
    • 字符串可以包含空格
  2. 处理要求:

    • 保持原有的空格
    • 完整反转整个字符串

代码

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

int main() {
    string str;
    // 使用getline读取整行,包括空格
    getline(cin, str);
    
    // 直接反转字符串
    reverse(str.begin(), str.end());
    
    cout << str << endl;
    return 0;
}
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        // 使用nextLine()读取整行,包括空格
        String str = sc.nextLine();
        
        // 使用StringBuilder反转字符串
        StringBuilder sb = new StringBuilder(str);
        System.out.println(sb.reverse().toString());
    }
}
while True:
    try:
        # 读取整行,包括空格
        s = input()
        # 使用切片反转字符串
        print(s[::-1])
    except:
        break

算法及复杂度

算法分析

  1. 输入处理:

    • 使用能读取整行的方法(包括空格)
    • C++使用 getline
    • Java使用 nextLine()
    • Python使用 input()
  2. 反转方法:

    • C++使用 algorithm 库的 reverse 函数
    • Java使用 StringBuilderreverse 方法
    • Python使用切片 [::-1]

复杂度分析

  • 时间复杂度: O ( n ) \mathcal{O}(n) O(n) - 其中 n n n 是字符串长度,需要遍历一次字符串
  • 空间复杂度: O ( 1 ) \mathcal{O}(1) O(1) - 原地反转不需要额外空间(某些语言实现可能需要 O ( n ) \mathcal{O}(n) O(n) 的空间)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值