/*
思路:
1.根据已知条件判断该整数 x 的上下限
由已知条件得
sqrt(x + 100) = y 由 y>=0 可知 x 的下限即为 -100
sqrt(x + 268) = z
由上面两式可得
z^2 - y^2 = 168
按照两个相邻整数的平方差间隔越来越大的特性,找出极限情况下的数值 y 与 z
将 z^2 - 268 或 y^2 - 100 作为 x 的上限
2.然后在范围内暴力搜索,找出所有符合描述的值
根据 x 的值计算 y, z
判断 y, z 均为整数,即输出 x
*/
# include <stdio.h>
# include <math.h>
int main()
{
int x, c1, c2, L, H;
c1 = 100;
c2 = 168;
L = -c1;
int i = 0;
for (i = 1; i*i - (i - 1)*(i - 1) <= c2; ++i)
;
H = i*i - (c1 + c2);
int j;
double y, z;
for (j = L; j <= H; ++j)
{
y = sqrt(j + c1);
z = sqrt(j + c1 + c2);
if (y == (int)y && z == (int)z)
printf("x的值为 %d\n", j);
}
return 0;
}
#include <stdio.h>
#include <math.h>
int main()
{
int n,x,a,m;
double b;
for (n = 1; n <= 168 / 2 ; n++)
{
x=n*n-100;
a=x+268;
b=sqrt(a);
if((int)b==b)
{
m=(int)b;
printf ("%d + 100 = %d * %d\n", x, n, n);
printf ("%d + 268 = %d * %d\n", x, m, m);
}
}
return 0;
}
1638c-exercise-example3
优化,有两点多余,i 可以从 2 开始加 2,i-j 必定是偶的:
#include <stdio.h>
int main (void)
{
int i, j, m, n, x;
for (i = 2; i <= 168 / 2; i=i+2)
{
if (168 % i == 0)
{
j = 168 / i;
if ( i > j && (i + j) % 2 == 0)
{
m = (i + j) / 2;
n = (i - j) / 2;
x = n * n - 100;
printf ("%d + 100 = %d * %d\n", x, n, n);
printf ("%d + 268 = %d * %d\n", x, m, m);
}
}
}
return 0;
}
1640c-exercise-example3
输出结果为:
1639c-exercise-example3
思路:
由 m^2 - n^2 = (m + n)(m - n) = 168, 得到 |m|>|n|
上式中 |n| 最大时则有:(n+1)^2-n^2≥168 → n≥83.5 , 故选择n的取值范围为1~84,
此时,x=n^2-100, m=(x+268)^0.5, 只需求得每个n所对应的x与m,再从中选择整型的x与m进行输出即可
程序:
1638c-exercise-example3
优化,有两点多余,i 可以从 2 开始加 2,i-j 必定是偶的:
1637c-exercise-example2
参考方法:
1636c-exercise-example2
对笔记2进行更正: