数学分析:
由题意我们可以设该数为
x
x
x,加100后得到的完全平方数为
y
2
y^2
y2,再加168后得到的完全平方数为
z
2
z^2
z2,则有:
{
x
+
100
=
y
2
y
2
+
168
=
z
2
\begin{cases} x+100=y^2 \\ y^2+168=z^2 \end{cases}
{x+100=y2y2+168=z2即得:
y
2
+
168
=
z
2
168
=
z
2
−
y
2
168
=
z
2
−
y
2
+
y
z
−
y
z
168
=
(
z
+
y
)
(
z
−
y
)
\begin{aligned} y^2+168 & = z^2 \\ 168 & = z^2-y^2 \\ 168 & =z^2-y^2+yz-yz \\ 168 & = (z+y)(z-y) \\ \end{aligned}
y2+168168168168=z2=z2−y2=z2−y2+yz−yz=(z+y)(z−y)这里分为四种情况:
- y > 0 , z > 0 y>0,z>0 y>0,z>0
- y > 0 , z < 0 y>0,z<0 y>0,z<0
- y < 0 , z > 0 y<0,z>0 y<0,z>0
- y < 0 , z < 0 y<0,z<0 y<0,z<0
若要得到 ( z + y ) ( z − y ) = 168 (z+y)(z-y)=168 (z+y)(z−y)=168,那么以上四种情况可以归为两类:
- 0 < ( z + y ) < 168 , 0 < ( z − y ) < 168 0<(z+y)<168,0<(z-y)<168 0<(z+y)<168,0<(z−y)<168
- − 168 < ( z + y ) < 0 , − 168 < ( z − y ) < 0 -168<(z+y)<0,-168<(z-y)<0 −168<(z+y)<0,−168<(z−y)<0
下面两个图是
y
y
y、
z
z
z、
z
+
y
z+y
z+y、
z
−
y
z-y
z−y的值域示意图,左图为
168
=
z
2
−
y
2
168=z^2-y^2
168=z2−y2,右图为
(
z
+
y
)
(
z
−
y
)
=
168
(z+y)(z-y)=168
(z+y)(z−y)=168:
实际上,无论 y y y与 z z z取何值,最终都能得到 y 2 + 168 = z 2 y^2+168=z^2 y2+168=z2,即 y y y、 z z z的取值不影响最终结果
这里设 y y y与 z z z都取正值,则 z + y z+y z+y、 z − y z-y z−y也为正值且其值大于 0 0 0小于等于 168 168 168。
另,由于: x + 100 = y 2 ⩾ 0 x+100=y^2\geqslant 0 x+100=y2⩾0因此可得 x ⩾ − 100 x\geqslant -100 x⩾−100.
所以我们可以利用的条件就是: { x + 100 = y 2 y 2 + 168 = z 2 z + y ∈ ( 0 , 168 ] z − y ∈ ( 0 , 168 ] x ⩾ − 100 \begin{cases} x+100=y^2 \\ y^2+168=z^2 \\ z+y \in(0,168] \\ z-y\in(0,168]\\ x\geqslant -100 \\ \end{cases} ⎩⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎧x+100=y2y2+168=z2z+y∈(0,168]z−y∈(0,168]x⩾−100
实现代码如下:
#include "stdio.h"
#include "math.h"
int main(void)
{
int x = -100;
double y = 0, z = 0;
// y+,z+,0<(z+y)<168,0<(z-y)<168
do {
y = sqrt(x + 100);
z = sqrt(x + 100 + 168);
if (y == (int)y && z == (int)z)
printf("%d\n", x);
x++;
} while ((z + y) > 0 && (z + y) <= 168);
/*
* y与z的另外三种取值,其结果与y+,z+一致
*
// y-,z-,-168<(z+y)<0,-168<(z-y)<0
do{
y = -sqrt(x + 100);
z = -sqrt(x + 100 + 168);
if (y == (int)y && z == (int)z)
printf("%d\n", x);
x++;
} while ((z + y) >= -168 && (z + y) < 0);
// y+,z-,-168<(z+y)<0,-168<(z-y)<0
do {
y = sqrt(x + 100);
z = -sqrt(x + 100 + 168);
if (y == (int)y && z == (int)z)
printf("%d\n", x);
x++;
} while ((z + y) >= -168 && (z + y) < 0);
// y-,z+,0<(z+y)<168,0<(z-y)<168
do {
y = -sqrt(x + 100);
z = sqrt(x + 100 + 168);
if (y == (int)y && z == (int)z)
printf("%d\n", x);
x++;
} while ((z + y) > 0 && (z + y) <= 168);
*
*
*/
return 0;
}
计算结果为:-99、21、261、1581