试题题目:
本题答案:2430 解题思路:
- 第一次编写程序:
?? 题目给出的
n
n
n数值为
16
16
16位数字,
C
C
C语言中有类型
l
o
n
g
long
long?
l
o
n
g
long
long?
i
n
t
int
int,其范围为
?
9223372036854775808
-9223372036854775808
?9223372036854775808~
9223372036854775807
9223372036854775807
9223372036854775807,为
19
19
19位数值完全可以存储
n
n
n;观察题目给出的例知:不需要进行去重处理。即虽因数相同,但所在位置不同,属于两种不同的方案。编写一个程序计算
n
n
n的所有因数,发现因数个数为
128
128
128个,可以简单地使用暴力的方法(三重循环),当符合
“
n
=
“n=
“n=因数1
?
*
?因数2
?
*
?因数3
”
”
”式子时,统计变量
s
u
m
sum
sum加一。代码如下:
#include<stdio.h>
#include<math.h>
#define n 2021041820210418
long long int inshu[1000];
int sum = 0;
int main(){
long long int geshu;
int i,j,z;
geshu = factor(n);
for(i=0;i<geshu;i++){
for(j=0;j<geshu;j++){
for(z=0;z<geshu;z++){
if(inshu[i] * inshu[j] *inshu[z] == n){
sum++;
}
}
}
}
printf("%d\n",sum);
return 0;
}
int factor(long long int N){
long long int i,k;
k = 0;
for(i=1; i<=sqrt(N); i++){
if(N%i == 0){
inshu[k++] = i;
}
}
if(sqrt(N) == inshu[k-1]){ i = k-1; }
else{ i = k; }
while(--i >= 0){
inshu[k++] = N / inshu[i];
}
return k;
}
- 第二次编写程序(第一次优化):
??暴力求解的方法,其时间复杂度为
O
(
n
3
)
O(n^3)
O(n3),造成了时间上的消耗,对上一个算法进行优化,优化方法为:通过调用
f
a
c
t
o
r
(
)
factor()
factor() 函数,找出n的所有因数,把
n
n
n拆分为
“
n
=
“n=
“n=因数1
?
*
?因数2
?
*
?因数3
”
”
”的式子;在对因数2调用
f
a
c
t
o
r
(
)
factor()
factor()找出因数2的所有因数,把因数2拆分为
“
“
“因数2
=
=
=因数21
?
*
?因数22
”
”
” 的式子;把这两个式子合并,便可以得出
“
n
=
“n=
“n=因数1
?
*
?因数2
?
*
?因数3
”
”
””,统计式子的个数,便可以得出答案。代码:
#include<stdio.h>
#include<math.h>
#define n 2021041820210418
int sum = 0;
long long int *factor(long long int N,long long int inshu[1000]);
int main(){
long long int yinshu[1000] = {0};
int i,j;
factor(n,yinshu);
for(i=0; i<yinshu[999]; i++){
long long int zinshu[1000] = {0};
factor(n/yinshu[i],zinshu);
for(j=0;j<zinshu[999]; j++){
sum++;
}
}
printf("%d\n",sum);
return 0;
}
long long int *factor(long long int N,long long int inshu[1000]){
long long int i,k;
k = 0;
for(i=1;i<=sqrt(N);i++){
if(N%i == 0){
inshu[k++] = i;
}
}
if(sqrt(N) == inshu[k-1]){ i = k-1; }
else{ i = k; }
while(--i >= 0){
inshu[k++] = N / inshu[i];
}
inshu[999] = k;
return inshu;
}
- 第三次编写程序(第二次优化)
??通过深度分析,比较上述两个算法,可以对以上算法进一步简化。 ??优化过程:因不需要去重,假设
f
1
?
f
2
?
f
3
=
n
f1 * f2 * f3 = n
f1?f2?f3=n ,根据这一个式子直接可以得出另外五个式子:“
f
1
?
f
3
?
f
2
=
n
f1 * f3 * f2 = n
f1?f3?f2=n ”、“
f
2
?
f
1
?
f
3
=
n
f2 * f1 * f3 = n
f2?f1?f3=n”、“
f
2
?
f
3
?
f
1
=
n
f2 * f3 * f1 = n
f2?f3?f1=n”、“
f
3
?
f
1
?
f
2
=
n
f3 * f1 * f2 = n
f3?f1?f2=n” 以及 “
f
3
?
f
2
?
f
1
=
n
f3 * f2 * f1 = n
f3?f2?f1=n”。 ??注意: ??(1)当
f
1
=
f
2
=
f
3
f1 =f2 = f3
f1=f2=f3时,
f
1
?
f
2
?
f
3
=
n
f1 * f2 *f3 = n
f1?f2?f3=n 只能算作一个式子; ??(2)当
f
1
=
f
2
f1 = f2
f1=f2 或者
f
1
=
f
3
f1=f3
f1=f3 或者
f
2
=
f
3
f2=f3
f2=f3时,
f
1
?
f
2
?
f
3
=
n
f1 * f2 * f3 = n
f1?f2?f3=n 改变位置后共得出三个式子; ??(3)当
f
1
≠
f
2
≠
f
3
f1 \neq f2 \neq f3
f1?=f2?=f3时,
f
1
?
f
2
?
f
3
=
n
f1 * f2 * f3 = n
f1?f2?f3=n ,可以算作六个不同式子; ??(4)为了避免重复计算,需要保证
f
1
≤
f
2
≤
f
3
f1 \le f2 \le f3
f1≤f2≤f3; ??以上两个算法,都使用了函数和数组,求因数再储存因数,消耗大量的存储空间。而求因数的过程特别简单,就是拿这个数(
n
n
n)除以小于它的数值(
i
i
i),如果能够被整除(
n
?
m
o
d
?
i
=
0
n \bmod i = 0
nmodi=0),那么
i
i
i就是它的第一个因数,
n
/
i
n/i
n/i就是它的第二个因数(
j
j
j)。用一个循环即可实现,循环条件设置为(
i
≤
s
q
r
t
(
n
)
i \le sqrt(n)
i≤sqrt(n)),保证了第一个因数小于第二个因数;再对第二个因数使用同样的循环,寻找出第二个因数的因数。第三个因数就是
n
/
i
/
j
n/i/j
n/i/j. 具体代码:
#include<stdio.h>
#include<math.h>
#define n 2021041820210418
int main(){
long long int i,j;
int sum = 0;
for(i=1;i<=sqrt(n);i++){
if(n%i == 0){
for(j=i;j<=sqrt(n/i);j++){
if(n/i%j == 0){
if(i==j && j==n/i/j){sum++;}
else if(i==j || j==n/i/j || i==n/i/j){sum+=3;}
else {sum+=6;}
}
}
}
}
printf("%d",sum);
}
|