预备知识:
算术基本定理(The fundamental theorem of arithmetic)
即唯一分解定理, 告诉我们每一个大于1 的整数若不是质数都可以写成有限多个质因子的乘积且经过适当排序其写法唯一。
I.一个合数的约数的个数是在严格分解质因数之后,将每个质因数的指数(次数)加1后 所得的乘积.如:1400严格分解质因数后为2^3×5^2×7,所以它的约数有(3+1)×(2+1)×(1+1)=4×3×2=24个.(包括1和它自身)
Ⅱ.约数的和是在严格分解质因数后,将M的每个质因数最高次幂的所有约数的和相乘所得到的积.如:21000=2^3×3×5^3×7,所以21000所有约数的和为(1+2+22+23)×(1+3)×(1+5+52+53)×(1+7)=74880.
2.判断m的约数个数:将m开方得n,判断n之前属于m的约数个数num。若n为整数,则m约数个数为2*num+1,否则为2*num
题目描述:
输入n个整数,依次输出每个数的约数的个数
输入:
输入的第一行为N,即数组的个数(N<=1000)
接下来的1行包括N个整数,其中每个数的范围为(1<=Num<=1000000000)
当N=0时输入结束。
输出:
可能有多组输入数据,对于每组输入数据,
输出N行,其中每一行对应上面的一个数的约数的个数。
样例输入:
5
1 3 4 6 12
样例输出:
1
2
3
4
6
来源:
2011年清华大学计算机研究生机试真题
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
int n;
while(cin>>n)
{
int num;
for(int i=1;i<=n;i++)//不使用数组的形式,每输入一个数就做判断,可能因为题目给的数据量很大所以耗时很严重
{
cin>>num;
int q=(int)sqrt(num);//这样做的目的是因为:if(a*b==num&&a!=b),那么其中一个必然小于sqrt(num);
int cnt=0,j;
for(j=1;j<=q;j++)//通过遍历比sqrt(num)小的每个数找出能够整除的那一个,则是num的约数
{
if(num%j==0)
cnt+=2;//因为整除一个数a也对应于整除另一个数b,所以+2
}
if(q*q==num)//当num能开整数的平方的时候,多算了q,要少计算一个
cnt-=1;
cout<<cnt<<endl;
}
}
return 0;
}
此博客的code部分均会详细的讲每一个地方为什么要这样写,因为我在编程时总会遇到各种各样智障的问题,所以我会着重的标记出来,希望能够帮助在编程路上刚起步的童鞋们~咱们一起进步!