欧拉工程第21题 计算10000以下所有相亲数之和

本文介绍了一种计算10000以下所有亲和数之和的方法,通过定义函数d(n)来求n的所有真因子之和,并利用相亲数的性质寻找配对的亲和数,最终计算这些亲和数的总和。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

d(n)定义为n 的所有真因子(小于 n 且能整除 n 的整数)之和。
如果 d(a)=b并且d(b)=a, 且 ab, 那么 a 和 b 就是一对相亲数(amicable pair),并且 a 和 b 都叫做亲和数(amicable number)。

例如220的真因子是 1, 2, 4, 5, 10, 11, 20, 22, 44, 55 和 110; 因此d(220)=284. 284的真因子是1, 2, 4, 71 和142; 所以d(284)=220.

计算10000以下所有亲和数之和。

解题方法

定一个函数d(n),求小于n的真因子数的和。solve函数里新建一个不重复的集合,将相亲数对加入,最后计算集合内数的和。
不过以下程序存在一个效率问题。如在solve中循环变量i = 220,获得另一个相亲数284,将这两个数添加至Set中。但在i=284时,220和284又一次添加至Set,虽然因为Set中已有这两个数而未重复添加,但实际上浪费了时间。这也是程序中使用Set的原因。如果不浪费效率,那么就需要一个布尔的数组标记哪个数已经被验证过,但这样也浪费了空间。在效率和占用空间中,我选择了减少空间。

程序

public static void solve() {
    // 新建一个空的内部元素不会重复的集合
    HashSet<Integer> amicable = new HashSet<Integer>();
    for (int i = 1; i < 10000; i++) {
        int amic = d(i);
        // 相亲数条件d(a) = b, d(b) = a,且a!=b
        if (i == d(amic) && i != amic) {
            // 输出相亲数对
            System.out.println(i + " | " + amic);
            amicable.add(i);
            amicable.add(amic);
        }
    }
    Iterator<Integer> it = amicable.iterator();
    int sum = 0;
    while (it.hasNext()) {
        int next = it.next();
        sum += next;
    }
    System.out.println(sum);
}

public static int d(int n) {
    int sum = 0;
    for (int i = 1; i <= n / 2; i++) {
        if (n % i == 0) {
            sum += i;
        }
    }
    return sum;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值