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

简介: 题目链接:http://ac.jobdu.com/problem.php?pid=1087 题目描述: 输入n个整数,依次输出每个数的约数的个数 输入: 输入的第一行为N,即数组的个数(N

题目链接: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))。

 

相关文章
|
4月前
|
Java
每日一题《剑指offer》数组篇之旋转数组的最小数字
每日一题《剑指offer》数组篇之旋转数组的最小数字
23 0
每日一题《剑指offer》数组篇之旋转数组的最小数字
|
6月前
【Leetcode -605.种花问题 -628.三个数的最大乘积】
【Leetcode -605.种花问题 -628.三个数的最大乘积】
15 0
|
8月前
|
存储 算法 测试技术
【AcWing每日一题】4653. 数位排序
【AcWing每日一题】4653. 数位排序
90 0
|
11月前
|
算法 C++ Python
每日算法系列【LeetCode 233】数字 1 的个数
每日算法系列【LeetCode 233】数字 1 的个数
|
11月前
|
算法 C++ Python
每日算法系列【LeetCode 829】连续整数求和
每日算法系列【LeetCode 829】连续整数求和
|
11月前
|
算法 C++ Python
每日算法系列【LeetCode 357】计算各个位数不同的数字个数
每日算法系列【LeetCode 357】计算各个位数不同的数字个数
|
11月前
|
人工智能 算法 vr&ar
每日算法系列【LeetCode 1004】最大连续1的个数 III
每日算法系列【LeetCode 1004】最大连续1的个数 III
|
11月前
leetcode剑指offer53–n-1中缺失的数字(二分//or等差数列)
leetcode剑指offer53–n-1中缺失的数字(二分//or等差数列)
LeetCode 1502. 判断能否形成等差数列
如果一个数列中,任意相邻两项的差总等于同一个常数,那么这个数列就称为 等差数列 。
75 0
|
算法 PHP
力扣(LeetCode)算法题解:1295. 统计位数为偶数的数字
力扣(LeetCode)算法题解:1295. 统计位数为偶数的数字
86 0

热门文章

最新文章