九度oj 题目1087:约数的个数

题目链接:http://ac.jobdu.com/problem.php?pid=1087

题目描述:

输入n个整数,依次输出每个数的约数的个数

输入:

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

输出:

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

样例输入:
5
1 3 4 6 12
样例输出:
1
2
3
4
6

这个题目呢,大家可以对比一下以下不同的做法。

代码一:九度oj测试结果耗时290ms。

 1 /*
 2  * Main.c
 3  *
 4  *  Created on: 2014年1月15日
 5  *      Author: Shaobo
 6  */
 7 #include <stdio.h>
 8 #include <stdlib.h>
 9 #include <math.h>
10   
11 int main(void){
12     int N;
13     int * data = NULL;
14     int i, j;
15     int cnt, tmp;
16   
17     while (scanf("%d", &N) == 1 && N != 0){
18         data = (int *)malloc(sizeof(int) * N);
19         if (data == NULL)
20             break;
21         for (i=0; i<N; ++i)
22             scanf("%d", &data[i]);
23         for (i=0; i<N; ++i){
24             cnt = 0;
25             for (j=1; j<=(int)sqrt(data[i]*1.0); ++j){
26                 if (data[i] % j == 0){
27                     cnt = cnt + 2;
28                 }
29             }
30             tmp = (int)(sqrt(data[i]*1.0));
31             if (tmp * tmp == data[i])
32                 --cnt;
33             printf("%d\n", cnt);
34         }
35         free(data);
36     }
37     return 0;
38 }

代码二:耗时间1000ms

 1 int main(void)
 2 {
 3     int N;
 4     int i, j;
 5     int cnt;
 6      
 7     int num;
 8     int t;
 9     while (scanf("%d", &N) == 1 && N != 0)
10     {
11         for (i=0; i<N; ++i)
12         {
13             scanf("%d", &num);
14             cnt =1;
15             for (j=2; j<=num;j++)
16             {
17                 t=0;
18                 while(num % j==0)
19                 {
20                     t++;
21                     num=num/j;  
22                 }
23                 cnt = cnt*(t+1);
24             }
25             printf("%d\n", cnt);
26         }
27     }
28     return 0;
29 }

代码三:耗时20ms

 1 int main(void)
 2 {
 3     int N;
 4     int i, j;
 5     int cnt;
 6      
 7     int num;
 8     int t;
 9     while (scanf("%d", &N) == 1 && N != 0)
10     {
11         for (i=0; i<N; ++i)
12         {
13             scanf("%d", &num);
14             cnt =1;
15             for (j=2; j*j<=num;j++)
16             {
17                 t=0;
18                 while(num % j==0)
19                 {
20                     t++;
21                     num=num/j;  
22                 }
23                 cnt = cnt*(t+1);
24             }
25             if(num>1) cnt=cnt*2;
26             printf("%d\n", cnt);
27         }
28     }
29     return 0;
30 }

 

关于代码二、三的原理,请看下面这个数学题:

 

代码二耗时较大的原因,我想应该是这样:

当num是一个比较大的质数时, while(num % j==0)的时间复杂度会退化到O(x)。采用类似代码一或代码三的借助sqrt的优化后,时间复杂度是O(sqrt(x))。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值