题目描述:输入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了,如果您有其他的观点或者觉得又可以改进的地方,请指出,谢谢!