第六章:求解500万以内的亲和数
2014-02-10 15:17
204 查看
亲和数问题
题目描述:
求500万以内的所有亲和数
如果两个数a和b,a的所有真因数之和等于b,b的所有真因数之和等于a,则称a,b是一对亲和数。
例如220和284,1184和1210,2620和2924。
注:
亲和数问题最早是由毕达哥拉斯学派发现和研究的。他们在研究数字的规律的时候发现有以下性质特点的两个数:
220的真因子是:1、2、4、5、10、11、20、22、44、55、110;
284的真因子是:1、2、4、71、142。
而这两个数恰恰等于对方的真因子各自加起来的和(sum[i]表示数i 的各个真因子的和),即
220=1+2+4+71+142=sum[284],
284=1+2+4+5+10+11+20+22+44+55+110=sum[220]。
得284的真因子之和sum[284]=220,且220的真因子之和sum[220]=284,即有sum[220]=sum[sum[284]]=284。
伴随数组线性遍历
题目描述:
求500万以内的所有亲和数
如果两个数a和b,a的所有真因数之和等于b,b的所有真因数之和等于a,则称a,b是一对亲和数。
例如220和284,1184和1210,2620和2924。
注:
亲和数问题最早是由毕达哥拉斯学派发现和研究的。他们在研究数字的规律的时候发现有以下性质特点的两个数:
220的真因子是:1、2、4、5、10、11、20、22、44、55、110;
284的真因子是:1、2、4、71、142。
而这两个数恰恰等于对方的真因子各自加起来的和(sum[i]表示数i 的各个真因子的和),即
220=1+2+4+71+142=sum[284],
284=1+2+4+5+10+11+20+22+44+55+110=sum[220]。
得284的真因子之和sum[284]=220,且220的真因子之和sum[220]=284,即有sum[220]=sum[sum[284]]=284。
伴随数组线性遍历
//求解亲和数问题 //第一个for和第二个for循环是logn(调和级数)*N次遍历,第三个for循环扫描O(N)。 //所以总的时间复杂度为 O(n*logn)+O(n)=O(N*logN)(其中logN为调和级数)。 //关于第一个for和第二个for寻找中,调和级数的说明: //比如给2的倍数加2,那么应该是 n/2次,3的倍数加3 应该是 n/3次,... //那么其实就是n*(1+1/2+1/3+1/4+...1/(n/2))=n*(调和级数)=n*logn。 //copyright@ 上善若水 //July、updated,2011.05.24。 #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; }
相关文章推荐
- 程序员编程艺术:第六章、求解500万以内的亲和数
- 程序员编程艺术:第六章、求解500万以内的亲和数
- 程序员编程艺术:第六章、求解500万以内的亲和数
- 【程序员编程艺术】第六章:求解500万以内的亲和数
- 程序员编程艺术:第六章、求解500万以内的亲和数
- 程序员编程艺术:第六章、求解500万以内的亲和数
- 程序员编程艺术:第六章、求解500万以内的亲和数
- 程序员编程艺术:第六章、求解500万以内的亲和数
- 求解500万以内的亲和数
- 006--求解500万以内的亲和数
- 第四章、亲和数问题--求解500万以内的亲和数
- 求解500万以内的亲和数
- 算法学习(五)求解500万以内的亲和数,连续数据映射为数组
- 亲和数问题--求解500万以内的亲和数之—Scheme语言实现
- 求500万以内的所有亲和数
- 求500万以内的所有亲和数
- 500万以内的亲和数
- 寻找500万以内的亲和数
- 10以内伐木问题递归求解
- 求解1-100以内约数个数是12个的数 (已知共有5个)