七夕节那天,月老来到数字王国,他在城门上贴了一张告示,并且和数字王国的人们说:"你们想知道你们的另一半是谁吗?那就按照告示上的方法去找吧!"
人们纷纷来到告示前,都想知道谁才是自己的另一半.告示如下:
值此七夕佳节来临之际,为感谢广大群众对我月老的热爱,特将大家的另一半的寻找方法公布如下:将你的编号(数字王国的每个人都有唯一的编号)所有因子加起来得到一个编号,这个编号的主人就是你的另一半。
祝大家找到自己的另一半。
———月老
数字N的因子就是所有比N小又能被N整除的所有正整数,如12的因子有1,2,3,4,6.
你想知道你的另一半吗?
Input
输入数据的第一行是一个数字T(1<=T<=500000),它表明测试数据的组数.然后是T组测试数据,每组测试数据只有一个数字N(1<=N<=500000).
Output
对于每组测试数据,请输出一个代表输入数据N的另一半的编号.
Sample Input
3
2
10
20
Sample Output
1
8
22
枚举方法
枚举到根号
time 468MS memory 1052K len 460 B
#include<stdio.h>
#include<math.h>
#define EOF 10e-6
int main()
{
int k,i,c;
scanf("%d ",&k);
for(i=0;i<k;i++)
{
int a,j,sum=0;
scanf("%d",&a);
c=sqrt(a)+EOF; //精度截断问题
for(j=2;j<=c;j++)
{
if(a%j==0)
{
if(j!=a/j) sum=sum+j+a/j; // eg:4=2*3;
else sum=sum+j; //eg:4=2*2;
}
}
sum++; //加上因子1;
printf("%d\n",sum);
}
return 0;
}
预处理
《1》
类似于筛法
比如2,3,4,5,6,7,8,9,10,11,12
当i=2时,所有2的倍数的数字都有因子2,
令a[4]=a[4](0)+i(2); a[6]=a[6](0)+i(2);
a[8]=a[8](0)+i(2) ...... a[12]=a[112](0)+i(2)
当i=3时,所有3的倍数的数字都有因子3,
此时a[6]=a[6](2)+i(3);.....a[12]=a[12]+i(3)
a[12]此后会依次加上i=4,i=6;
最后输出结果在加上因子1;
time 78MS memory 3012K len 334 B
#include<stdio.h>
int a[500001];
int main()
{
int i,j,k,n;
for(i=2;i<=250000;i++)
{
for(j=i+i;j<=500000;j=j+i)
a[j]=a[j]+i;
}
scanf("%d",&k);
while(k--)
{
scanf("%d",&n);
if(n==1) printf("0\n");
else printf("%d\n",a[n]+1);
}
return 0;
}
《2》
也可以先加上因子1;再处理
两种写法意思一样;
但速度会变慢
time 124MS memory 3012K len 319 B
#include<stdio.h>
int a[500001];
int main()
{
int i,j,k,n;
for(i=0;i<500001;i++) a[i]=1;
for(i=2;i<500001;i++)
{
for(j=2;j*i<500001;j++)
a[j*i]+=i;
}
scanf("%d",&k);
while(k--)
{
scanf("%d",&n);
printf("%d\n",a[n]);
}
return 0;
}