面试算法记录
来源:互联网 发布:爱国者之日 知乎 编辑:程序博客网 时间:2024/06/07 03:24
1.亲和数问题:
求500万以内的所有亲和数
如果两个数a和b,a的所有真因数之和等于b,b的所有真因数之和等于a,则称a,b是一对亲和数。
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万以内的所有亲和数
如果两个数a和b,a的所有真因数之和等于b,b的所有真因数之和等于a,则称a,b是一对亲和数。
例如220和284,1184和1210,2620和2924。
思路:
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。
求解步骤如下:
因为所有数的真因数都包含1,所以,先在各个数的下方全部置1
- 然后取i=2,3,4,5(i<=10/2),j依次对应的位置为j=(4、6、8、10),(6、9),(8),(10)各数所对应的位置。
- 依据j所找到的位置,在j所指的各个数的下面加上各个真因子i(i=2、3、4、5)。
整个过程,即如下图所示(如sum[6]=1+2+3=6,sum[10]=1+2+5=8.):
1 2 3 4 5 6 7 8 9 10
1 1 1 1 1 1 1 1 1 1
2 2 2 2
3 3
4
5 - 然后一次遍历i从220开始到5000000,i每遍历一个数后,
将i对应的数下面的各个真因子加起来得到一个和sum[i],如果这个和sum[i]==某个i’,且sum[i‘]=i,
那么这两个数i和i’,即为一对亲和数。 - i=2;sum[4]+=2,sum[6]+=2,sum[8]+=2,sum[10]+=2,sum[12]+=2...
i=3,sum[6]+=3,sum[9]+=3...
...... - i=220时,sum[220]=284,i=284时,sum[284]=220;即sum[220]=sum[sum[284]]=284,
得出220与284是一对亲和数。所以,最终输出220、284,...
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;
}
0 0
- 面试算法记录
- 值得记录的面试题目(算法工程师)
- 面试记录-数据开发/算法/JAVA
- 面试记录
- 面试记录
- 面试记录
- 面试记录
- 面试记录
- 面试记录
- 面试记录
- 面试记录
- 面试记录
- 面试记录
- 面试记录
- 面试记录
- 面试记录
- 面试记录
- 面试记录
- POJ 1008 滑雪
- HDU 4973 A simple simulation problem.(线段树)
- HDU - 4974 A simple water problem
- Remember the Word - UVaLive 3942 Trie树+dp
- Lucene从入门到熟悉(三)分词
- 面试算法记录
- 按键消抖
- 戒骄戒躁,qt相关学习资料
- HDU 4974 A simple water problem(贪心)
- 协议系列之UDP协议
- IOS学习笔记-2
- STL map用法
- 【转】单例模式
- NSArray元素去重