题目来源:2011年清华大学计算机研究生机试真题
-
题目描述:
- 输入n个整数,依次输出每个数的约数的个数
-
输入:
-
输入的第一行为N,即数组的个数(N<=1000)
接下来的1行包括N个整数,其中每个数的范围为(1<=Num<=1000000000)
当N=0时输入结束。
-
输出:
-
可能有多组输入数据,对于每组输入数据,
输出N行,其中每一行对应上面的一个数的约数的个数。
-
样例输入:
-
5 1 3 4 6 12
-
样例输出:
-
1 2 3 4 6
此题解法比较多。
1) 可以直接暴力求解,用类似找素数的方法。循环到 sqrt(n) 逐个判断.
01 | #include <iostream> |
02 | #include <cmath> |
03 |
04 | using namespace std; |
05 |
06 | int main( void ) |
07 | { |
08 | int n; |
09 | while (cin >> n) |
10 | { |
11 | int num; |
12 | while (n--) |
13 | { |
14 | int count = 0; |
15 | cin >> num; |
16 |
17 | int i; |
18 | for (i = 1; i < sqrt (( double )num); i++) |
19 | { |
20 | if (num % i == 0) |
21 | { |
22 | count += 2; |
23 | } |
24 | } |
25 | if (i * i == num) |
26 | { |
27 | count++; |
28 | } |
29 | cout << count << endl; |
30 | } |
31 | } |
32 | return 0; |
33 | } |
2) 用约数个数定理。百科:http://baike.baidu.com/view/1780622.htm
用约数个数定理做的,只贴出功能函数,主函数里面调用该函数即可。
01 | unsigned int factors(unsigned int n) |
02 | { |
03 | unsigned int i = 2, k = 0, m = n, count = 1; |
04 | while (m != 1) |
05 | { |
06 | for (; i <= m; i ++) |
07 | if (m % i == 0) |
08 | { |
09 | k = 1; |
10 | while (m % i == 0) |
11 | { |
12 | k ++; |
13 | m /= i; |
14 | } |
15 | count *= k; |
16 | } |
17 | } |
18 | return count; |
19 | } |
不用进行素数判定,for循环找到的 i 一定是素数。
自认为该算法应该算比较简洁明了的。
经验证,平均性能比穷举法(O(n))的速度快很多,10^12左右的合数都能瞬间出结果,穷举法要好几秒(不过对于素数,该算法就退化为穷举法了,也就是说最坏情况下时间复杂度为O(n))。