【编程笔记】求一个数的约数个数

按照最简单的思考方法,是使用枚举法,将这个数除以小于这个数的所有正整数,如果没有余数,则为该数字的约数。
这种线性方法虽然思考起来简单,但一旦要计算的数字特别大时,则会超时。

还有一种较为简单的思考方式,那就是只枚举到根号该数字
举个栗子:
如果要求20的约数:1,2,4,5,10,20事实上我们不需要讲所有数字都试一遍,如果20可以被1整除,则其商20一定也为其约数;如果20可以被2整除,那其商10一定也为其约数... ...
再举个特殊的栗子:
如果要求16的约数:1,2,4,8,16,由于25本身是5*5的积,但是我们只能算5一个约数,所以一旦该数字是一个数的平方时,我们只需要统计枚举到小于该数的根号,然后加上这个值就行。

具体实现办法:

#include <stdio.h>
int Count(int n)
{
	int count = 0;
	int i;
	for (i = 1; i*i< n; i++)
	{
		if (n%i == 0)
			count+=2;
	}
	if (i*i == n)
		count++;
	return count;
}
int main()
{
	int num;
	int a[100];
	scanf("%d", &num);

	for (int i = 0; i<num; i++)
	{
		scanf("%d",	 &a[i]);
	}
	for (int i = 0; i<num; i++)
	{
		printf("%d\n", Count(a[i]));
	}
	return 0;
}

当然还有更简单的方法,考虑下我们小时候学过的分解质因数的知识。
360=2*2*2*3*3*5=2^3+3^2+5

那么360的约数只能为2^a*3^b*5^c2(a的范围(0-3),b的范围(0-2),c的范围(0-1)),因此360的约数有4*3*2=24个。
具体实现方法:
#include <stdio.h>
int main()
{
	int n, m, ans, num;
	while (scanf("%d", &n) != EOF)			//从标准输入中获取此次要计算的数字个数n
	{
		for (int i = 0; i < n; i++)
		{
			scanf("%d", &m);
			ans = 1;
			for (int i = 2; i*i <= m; i++)
			{
				num = 0;		//num表示相同因子的个数
				while (m%i == 0)        //统计该数字m能被当前枚举的质数i整除多少次(事实上如果不是质数这里是不会进入循环的,因为此时已经被比非质数i小的质数分解过了)
				{
					num++;
					m = m / i;
				}
				if (num > 0)         //如果可以被此质数整除,则加一(加上零次方的可能性)
				{
					num++;
					ans = ans * num;
				}
			}
			if (m > 1) ans = ans * 2;    //如果已经把小于根号m的数字都枚举过了但还未将m分解完,则说明还有一个大于根号m的质数约数,因此乘以2
			printf("%d\n", ans);
		}
	}
	return 0;
}


猜你喜欢

转载自blog.csdn.net/yong_ss/article/details/79356836