UVA 294 Divisors( 因子分解)

294 Divisors
Mathematicians love all sorts of odd properties of numbers. For instance, they consider 945 to be an
interesting number, since it is the rst odd number for which the sum of its divisors is larger than the
number itself.
To help them search for interesting numbers, you are to write a program that scans a range of numbers
and determines the number that has the largest number of divisors in the range. Unfortunately, the size
of the numbers, and the size of the range is such that a too simple-minded approach may take too much
time to run. So make sure that your algorithm is clever enough to cope with the largest possible range
in just a few seconds.
Input Speci cation
The rst line of input speci es the number N of ranges, and each of the N following lines contains a
range, consisting of a lower bound L and an upper bound U, where L and U are included in the range.
L and U are chosen such that 1  L  U  1000000000 and 0  U
L  10000.
Output Speci cation
For each range, nd the number P which has the largest number of divisors (if several numbers tie for
rst place, select the lowest), and the number of positive divisors D of P (where P is included as a
divisor). Print the text 'Between L and H, P has a maximum of D divisors.', where L, H, P ,
and D are the numbers as de ned above.
Example input
3
1 10
1000 1000
999999900 1000000000
Example output
Between 1 and 10, 6 has a maximum of 4 divisors.
Between 1000 and 1000, 1000 has a maximum of 16 divisors.
Between 999999900 and 1000000000, 999999924 has a maximum of 192 divisors.

题目大意:

  这道题是说给你一个[l,r]的区间,让你求出这个区间中因子最多的数的个数。

解题思路:

  由唯一分解定理我们知道,对于任意个整数我们都能写成:val = p_1*a^1*p_2*a^2*p_3*a^3*...p_i*a^i的形式,那么我们只需要把[l,r]区间内的任意一个数

拆成这样的形式就行了,然后该怎么统计这个数字的因子的个数呢?其实通过这样的方法就可以了,比如24 = 2^3*3^1 ,我们知道24有8个因子,所以,我们得到了

(3+1)*(1+1) = 8 的计算方法,也就是说统计每个素数因子的次幂,然后(次幂+1)做乘积就是答案了

代码:

 1 # include<cstdio>
 2 # include<iostream>
 3 
 4 using namespace std;
 5 
 6 # define MAX 32000 //sqrt(10^9)
 7 
 8 int book[MAX];
 9 int prime[MAX];
10 int len;
11 
12 void init()
13 {
14     for ( int i = 2;i <= MAX;i++ )
15     {
16         book[i] = 1;
17     }
18     for ( int i = 2;i <= MAX;i++ )
19     {
20         if ( book[i]==1 )
21         {
22             for ( int j = 2*i;j <= MAX;j+=i )
23             {
24                 book[j] = 0;
25             }
26         }
27     }
28 
29     len = 0;
30     for ( int i = 2;i <= MAX;i++ )
31     {
32         if ( book[i]==1 )
33         {
34             prime[len++] = i;
35         }
36     }
37 }
38 
39 int cal ( int x )
40 {
41     int tot = 0;
42     int cnt = 1;
43     for ( int i = 0;i < len;i++ )
44     {
45         if ( x==1 )
46             break;
47         if ( x%prime[i]==0 )
48         {
49             tot = 1;
50             while ( x%prime[i]==0 )
51             {
52                 x/=prime[i];
53                 tot++;
54             }
55             cnt *= tot;
56         }
57     }
58     return cnt;
59 }
60 
61 int main(void)
62 {
63     init();
64     int t;cin>>t;
65     while ( t-- )
66     {
67         int ans = 0;
68         int val = 0;
69         int l,r;
70         cin>>l>>r;
71         for ( int i = l;i <= r;i++ )
72         {
73             if ( cal(i) > ans )
74             {
75                 ans = cal(i);
76                 val = i;
77             }
78         }
79         printf("Between %d and %d, %d has a maximum of %d divisors.
",l,r,val,ans);
80     }
81 
82 
83 
84     return 0;
85 }
原文地址:https://www.cnblogs.com/wikioibai/p/4451798.html