首页 > 代码库 > 算法进化历程之相亲数
算法进化历程之相亲数
算法进化历程之相亲数
巧若拙(欢迎转载,但请注明出处:http://blog.csdn.net/qiaoruozhuo)
题目来自于编程论坛“吴健飞飞”的提问:求4位数以内的相亲数对
2500年前数学大师毕达哥拉斯发现,220与284两数之间存在下列奇妙的联系:220的真因数之和为1+2+4+5+10+11+20+22+44+55+110=284
284的真因数之和为1+2+4+71+142=220
毕达哥拉斯把这样的数对a,b称为相亲数:a的真因数(小于本身的因数)之和为b,而b的真因数之和为a。
版主rjsp给出了两个精妙的算法,我对其进行了整理,作出此文。对为此文提供灵感的网友表示感谢。
#include<stdio.h> #include<stdlib.h> #include<math.h> #include<time.h> void AmicablePair_1(int n);//求相亲数的原始方法 void AmicablePair_2(int n);//以空间换时间 void AmicablePair_3(int n);//用加法运算代替求余运算,更加高效 int main(void) { unsigned n = 1000000; clock_t begin, end; double cost; begin = clock(); AmicablePair_1(n);//求相亲数的原始方法 end = clock(); cost = (double)(end - begin) / CLOCKS_PER_SEC; printf("%lf seconds\n", cost); begin = clock(); AmicablePair_2(n);//求相亲数的原始方法 end = clock(); cost = (double)(end - begin) / CLOCKS_PER_SEC; printf("%lf seconds\n", cost); begin = clock(); AmicablePair_3(n);//求相亲数的原始方法 end = clock(); cost = (double)(end - begin) / CLOCKS_PER_SEC; printf("%lf seconds\n", cost); return 0; } void AmicablePair_1(int n)//求相亲数的原始方法 { unsigned i, j, sa, sb; for (i=2; i<=n; i++) { sa = 1; for (j=sqrt(i); j>1; j--)//计算i的真因数和 { if (i % j == 0) sa += j + i / j; } if (sa <= i)//确sa>i,以避免重复计算 continue; sb = 1; for (j=sqrt(sa); j>1 && sb<=i; j--)//计算sa的真因数和 { if (sa % j == 0) sb += j + sa / j; } if (sb == i) printf( "%u\t%u\n", i, sa); } } void AmicablePair_2(int n)//以空间换时间 { unsigned i, j; int *p = (unsigned*)malloc(sizeof(unsigned)*(n+1)); if( !p ) { printf("Out of space!"); exit(0); } for (i=2; i<=n; i++) { p[i] = 1; for (j=sqrt(i); j>1; j--)//计算i的真因数和,并存储在p[i]中 { if (i % j == 0) p[i] += j + i / j; if (p[i] > n) { p[i] = 0; break; } } } for (i=2; i<=n; i++) { if (p[p[i]] == i && i < p[i]) //相亲数对 printf( "%u\t%u\n", i, p[i]); } free(p); } void AmicablePair_3(int n)//用加法运算代替求余运算,更加高效 { unsigned i, j, mid; int *p = (unsigned*)malloc(sizeof(unsigned)*(n+1)); if( !p ) { printf("Out of space!"); exit(0); } mid = n / 2; for (i=1; i<=mid; i++) { for (j=i*2; j<=n; j+=i)//因为j是i的倍数,故i之和即j的真因数和 { p[j] += i; } } for (i=2; i<n; i++) { if (p[i] <= n && p[p[i]] == i && i < p[i]) //相亲数对 printf( "%u\t%u\n", i, p[i]); } free(p); }
算法进化历程之相亲数
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。