题目
如果一个数的所有真因子之和等于这个数,那么这个数被称为完全数。例如,28的所有真因子之和为 1+2+4+7+14=28 ,所以28是一个完全数。
如果一个数的所有真因子之和小于这个数,称其为不足数,如果大于这个数,称其为过剩数。
12是最小的过剩数, 1+2+3+4+6=16 。因此最小的能够写成两个过剩数之和的数字是24。经过分析,可以证明所有大于28123的数字都可以被写成两个过剩数之和。但是这个上界并不能被进一步缩小,即使我们知道最大的不能表示为两个过剩数之和的数字要比这个上界小。
找出所有不能表示为两个过剩数之和的正整数之和。
解题方法
构建一个isOverNum方法,判断一个数是否为过剩数,并计算小于等于28123的所有过剩数,并添加到一个ArrayList中。然后判断从1开的数能否以list中数和的形式表示,能则添加到sum中,不能则判断下一个数。
程序
程序的效率有点低,花了26秒,计算过剩数花了600ms,转换成int数组花了33ms,所以还是最后筛选部分算法效率比较低。
public static void solve() {
// 计算28213以下的过剩数
ArrayList<Integer> list = new ArrayList<Integer>();
for (int num = 2; num <= 28123; num++) {
if (isOverNum(num) > 0) {
list.add(num);
}
}
//转换为int数组
int[] overNum = new int[list.size()];
for (int i = 0;i<list.size();i++) {
overNum[i] = list.get(i);
}
int sum = 0;
// 筛选不能表示为2个过剩数之和的数,叠加至sum
for (int num = 1; num <= 28123; num++) {
int i = 0;
for (; i < overNum.length; i++) {
if (overNum[i] > num /2){
sum += num;
break;
}
if (list.contains(num - overNum[i])) {
break;
}
}
}
System.out.println(sum);
}