九度-1044-Pre-Post[分治和组合数]

题目来源: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))。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值