求500萬以內的所有親和數
如果兩個數a和b,a的所有真因數之和等於b,b的所有真因數之和等於a,則稱a,b是一對親和數。
例如220和284,1184和1210,2620和2924。
思路:利用數組記錄從1-5,000,000
#include<stdio.h>
int sum[5000010]; //爲防越界
int main()
{
int i, j;
for (i = 0; i <= 5000000; i++)
sum[i] = 1; //1是所有數的真因數所以全部置1
for (i = 2; i + i <= 5000000; i++) //預處理,預處理是logN(調和級數)*N。
//@litaoye:調和級數1/2 + 1/3 + 1/4......的和近似爲ln(n),
//因此O(n *(1/2 + 1/3 + 1/4......)) = O(n * ln(n)) = O(N*log(N))。
{
//5000000以下最大的真因數是不超過它的一半的
j = i + i; //因爲真因數,所以不能算本身,所以從它的2倍開始
while (j <= 5000000)
{
//將所有i的倍數的位置上加i
sum[j] += i;
j += i;
}
}
for (i = 220; i <= 5000000; i++) //掃描,O(N)。
{
// 一次遍歷,因爲知道最小是220和284因此從220開始
if (sum[i] > i && sum[i] <= 5000000 && sum[sum[i]] == i)
{
//去重,不越界,滿足親和
printf("%d %d/n",i,sum[i]);
}
}
return 0;
}