题目地址:
http://acm.hdu.edu.cn/showproblem.php?pid=1215
<br />
http://acm.hdu.edu.cn/showproblem.php?pid=1215
<br />
两个解题思路:
一是,穷举,2到那个数n的所有数,对n整除,能整除就是约数,然后相加。当然,去掉数n自身。
二是,化简为素数方幂的乘积,我估计这个算法跟素数方幂的乘积有关。当然,去掉数n自身。
一个搜索到的解题代码:
#include <stdlib.h>
#define MAX 5000
int flag[MAX];
int main(int argc,char *argv[])
{
int T,n,i,j;
flag[1]=0;
for(i=2;i<MAX;i++)//每个数的因子之和预设值为1
{
flag[i]=1;
}
for(i=2;i<=2500;i++)//首先对2进行因子求和,进行一半循环,
{
j=i+i;//只要是i的倍数,肯定会有i这个因子,
while(j<MAX)
{
flag[j]=flag[j]+i;//所以把i加上去
j=j+i;//只要是i的倍数,肯定会有i这个因子,
}
}
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
printf("%d\n",flag[n]);
}
}
#define MAX 5000
int flag[MAX];
int main(int argc,char *argv[])
{
int T,n,i,j;
flag[1]=0;
for(i=2;i<MAX;i++)//每个数的因子之和预设值为1
{
flag[i]=1;
}
for(i=2;i<=2500;i++)//首先对2进行因子求和,进行一半循环,
{
j=i+i;//只要是i的倍数,肯定会有i这个因子,
while(j<MAX)
{
flag[j]=flag[j]+i;//所以把i加上去
j=j+i;//只要是i的倍数,肯定会有i这个因子,
}
}
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
printf("%d\n",flag[n]);
}
}
再解说:比如要6的因子之和,6有因子1,2,3,所以6的因子之和为6.
循环的时候,当i=2,flag[2]=1,flag[4]=1+2=3,flag[6]=3;当i=3,flag[3]=1,flag[6]=flag[6]+3=6,flag[9]=flag[9]+3=4。
在i=3的时候,你会发现,能被2整除,又能被3整除的数z,也就是flag[z]=6,而flag[只能被3整除的]=4。
也就是说,一个数的约数之和(不加自身),等于第三大约数的因子修改值+第二大约数。。。