您的位置:首页 > 其它

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

2016-10-19 20:47 351 查看

题目

d(n)定义为n 的所有真因子(小于 n 且能整除 n 的整数)之和。

如果 d(a)=b并且d(b)=a, 且 a≠b, 那么 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐