约数的个数

题目描述:输入n个整数,依次输出每个数的约数的个数。

输入描述:输入的第一行为N,即数组的个数(N<=1000),接下来的1行包括N个整数,其中每个数的范围为(1<=Num<=1000000000),当N=0时输入结束。

输出描述:可能有多组输入数据,对于每组输入数据,输出N行,其中每一行对应上面的一个数的约数的个数。

分析:如何求一个数的约数个数,常规的就是从1- n(表示这个数本身),设为i。如果n% i == 0,则说明i是它的约数,计数器count ++。但是这样写,复杂度不满足提交需求。

1、所以介绍一个约数个数定理:

对于一个大于1正整数n可以分解质因数: 
则n的正约数的个数就是 

其中a1、a2、a3…ak是p1、p2、p3,…pk的指数。

2、但是我们是将n开根号,即sqrt(n),然后求1-sqrt(n)中的约数个数,记作num。令m = sqrt(n), 如果m 是整数,num * 2 + 1, 否则是2 * num。

参考代码:

#include<iostream>
#include<math.h>
using namespace std;
// 求约数时,如果完全遍历,复杂度太大,所以使用开根号的方式。 
int main(){

	int n;
	while(cin >> n && n != 0){
		int a[n];
		for(int i = 0; i < n; i ++){
			cin >> a[i];
            int count = 0;
            int m = sqrt(a[i]);
            for(int j = 1; j <= m; j ++){
            if(a[i] % j == 0){
            	count += 2;		
			}
			}
			if(m * m == a[i]){
				count --;
			}
            
			cout << count << endl;
		}
		
	}
	return 0;
} 

此外需要注意的是,它是以0作为结束标志, 如果是使用scanf,那么他结束的标志记得改为0, 而不是EOF。



这个题目是在牛客网在线编程中提交的,已经ac了,如果您有其他的观点或者觉得又可以改进的地方,请指出,谢谢!

猜你喜欢

转载自blog.csdn.net/kobe_jr/article/details/80034594