C语言学习-菜鸟教程C经典100例-练习3
C语言学习-菜鸟教程C经典100例-练习3
题目
一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少?
思路
设这个整数为 x x x;
- 加上100是完全平方数: x + 100 = m 2 x + 100 = m^2 x+100=m2;
- 再加上168又是完全平方数: x + 100 + 168 = n 2 x + 100 + 168 = n^2 x+100+168=n2;
- 两式合并: n 2 − m 2 = 168 n^2 - m^2 = 168 n2−m2=168;
- 解方程: n 2 − m 2 = ( n + m ) ( n − m ) = 168 n^2 - m^2 = (n+m)(n-m) = 168 n2−m2=(n+m)(n−m)=168;
- 设置 i , j i,j i,j: i = n + m , j = n − m i = n+m, j = n-m i=n+m,j=n−m; 则 i ∗ j = 168 i*j = 168 i∗j=168;
- 代入可得:
n
=
(
i
+
j
)
/
2
,
m
=
(
i
−
j
)
/
2
n = (i+j)/2, m = (i-j)/2
n=(i+j)/2,m=(i−j)/2;
- 由 n , m n,m n,m都是整数可知: i , j i,j i,j 都是整数;
- 由
n
,
m
n,m
n,m都是正数(完全平方根)且
m
<
n
m<n
m<n 可知:
i
>
j
>
0
i>j>0
i>j>0;
- 关于
i
,
j
i,j
i,j的奇偶性:
- i + j = ( n + m ) + ( n − m ) = 2 n i+j = (n+m)+(n-m) = 2n i+j=(n+m)+(n−m)=2n => 偶数
- i − j = ( n + m ) − ( n − m ) = 2 m i-j = (n+m)-(n-m) = 2m i−j=(n+m)−(n−m)=2m => 偶数
- 可得: i , j i,j i,j同奇同偶;
- 根据
i
∗
j
=
168
i*j=168
i∗j=168 可知:
i
,
j
i,j
i,j同为偶数;
- 确定范围:
- 由 (1) i ∗ j = 168 i*j=168 i∗j=168, (2) i , j i,j i,j同为偶数, (3) i > j > 0 i>j>0 i>j>0 可知: j > = 2 j>=2 j>=2, 且 i = 168 / j < = 168 / 2 = 84 i = 168/j <= 168/2=84 i=168/j<=168/2=84;
- 故范围为:
2
<
=
i
<
=
84
,
j
>
=
2
2 <= i <= 84, j >= 2
2<=i<=84,j>=2;
- 由
i
,
j
i,j
i,j 的值往回退找到
x
x
x:
- 由 n = ( i + j ) / 2 , m = ( i − j ) / 2 n=(i+j)/2, m=(i-j)/2 n=(i+j)/2,m=(i−j)/2, 可知 x = m 2 − 100 x=m^2-100 x=m2−100;
代码
#include <stdio.h>
int main(){
int x;
int m, n;
int i, j;
int count=0;
for(i=2; i<=84; i=i+2){ // i是从2开始的偶数
if(168%i == 0){ // i能够被168整除(根据i*j=168)
j = 168/i;
if(j>=2 && i>j && (i+j)%2==0){
// 计算m,n
m = (i-j) / 2;
n = (i+j) / 2;
//计算x
x = m*m - 100;
count++;
printf("第%d个数是:%d \n", count, x);
printf("%d + 100 = %d * %d \n", x, m, m);
printf("%d + 100 + 168 = %d * %d \n", x, n, n);
printf("\n");
}
}
}
return 0;
}
输出结果
第1个数是:-99
-99 + 100 = 1 * 1
-99 + 100 + 168 = 13 * 13
第2个数是:21
21 + 100 = 11 * 11
21 + 100 + 168 = 17 * 17
第3个数是:261
261 + 100 = 19 * 19
261 + 100 + 168 = 23 * 23
第4个数是:1581
1581 + 100 = 41 * 41
1581 + 100 + 168 = 43 * 43
# 一个暴力遍历x的方法
思路
-
设这个数是
x; -
在
x的取值范围中遍历,判断每一个x是不是符合条件; -
难点是要确定
x的范围; -
由题可知: x + 100 = m 2 , x + 100 + 168 = n 2 x + 100 = m^2, x + 100 + 168 = n^2 x+100=m2,x+100+168=n2;
-
由 x + 100 = m 2 x + 100 = m^2 x+100=m2 可知: x > = − 100 x>=-100 x>=−100;
-
n 2 − m 2 = 168 n^2 - m^2 =168 n2−m2=168, 当
m增大时,n也增大,n和m越来越接近; -
找出最大的
m:- 设
n = m + 1; (这是n比m大的最小整数差) - 那么 ( m + 1 ) 2 − m 2 = 168 (m+1)^2 - m^2 = 168 (m+1)2−m2=168;
- 计算得:
m = 83.5; - 所以在
m>83的时候,不管n取多少,都不能满足 n 2 − m 2 = 168 n^2-m^2=168 n2−m2=168;- 解释:当
m=84时,n=85, n 2 − m 2 = 169 n^2-m^2=169 n2−m2=169,大于168; - 所以,其他的
n的取值都不会再满足 n 2 − m 2 = 168 n^2-m^2=168 n2−m2=168;
- 解释:当
- 最终取得最大的
m为83;
- 设
-
根据最大的
m,可以找到x的上界:- 当 $
m=84时, x = 84 ∗ 84 − 100 = 6956 x = 84*84 - 100 = 6956 x=84∗84−100=6956;
- 当 $
-
最终得到
x的范围是[-100, 6956];
代码
#include <stdio.h>
#include <math.h> // 包含头文件math.h,里面有sqrt()函数
int main(){
int x;
int count = 0;
for(x=-100; x<=6956; x++){
int m = sqrt(x + 100); // 计算x + 100的平方根m
int n = sqrt(x + 100 + 168); // 计算x + 100 + 168的平方根n
// sqrt()函数返回一个double型的平方根;
// 在这里强制转换为int类型,出现截断取整;
// 只有正好是整数的平方根没有变化,在后面的判断中可以返回计算出正确的数值;
// 检查判断是否是完全平方
if(m*m == x + 100 && n*n == x + 100 + 168){
count++;
printf("第%d个数是:%d \n", count, x);
printf("%d + 100 = %d * %d \n", x, m, m);
printf("%d + 100 + 168 = %d * %d \n", x, n, n);
printf("\n");
}
}
return 0;
}
# 一个遍历m的方法(遍历效率高一点)
思路
-
设这个数是
x; -
设 x + 100 = m 2 , x + 100 + 168 = n 2 x + 100 = m^2, x + 100 + 168 = n^2 x+100=m2,x+100+168=n2;
-
因为是完全平方数,所以必须满足
n>m>0; -
找出最大的
m:- 设
n = m + 1; (这是n比m大的最小整数差) - 那么 ( m + 1 ) 2 − m 2 = 168 (m+1)^2 - m^2 = 168 (m+1)2−m2=168;
- 计算得:
m = 83.5; - 所以在
m>83的时候,不管n取多少,都不能满足 n 2 − m 2 = 168 n^2-m^2=168 n2−m2=168;- 解释:当
m
=
84
m=84
m=84 时,
n
=
85
,
n
2
−
m
2
=
169
n=85,n^2-m^2=169
n=85,n2−m2=169,大于
168; - 所以,其他的
n的取值都不会再满足 n 2 − m 2 = 168 n^2-m^2=168 n2−m2=168;
- 解释:当
m
=
84
m=84
m=84 时,
n
=
85
,
n
2
−
m
2
=
169
n=85,n^2-m^2=169
n=85,n2−m2=169,大于
- 设
-
最终取得最大的
m为83; -
故m的取值范围是
[0,83]; -
通过遍历
m,然后计算n并取平方根作比较来判断x是否满足条件;
代码
#include <stdio.h>
#include <math.h>
int main(){
int x;
int m, n;
int count = 0;
for(m=0; m<84; m++){
int temp = m*m + 168; // n^2 = m^2 + 168
int n = sqrt(m*m + 168); // 计算n的平方根
if(n*n == temp){ // 判断是否为完全平方
count++;
x = m*m - 100;
printf("第%d个数是:%d \n", count, x);
printf("%d + 100 = %d * %d \n", x, m, m);
printf("%d + 100 + 168 = %d * %d \n", x, n, n);
printf("\n");
}
}
return 0;
}
更多推荐



所有评论(0)