1. 题目
一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少?
2. 分析
咱们先以数学的角度分析
假设该数为 x。步骤1
:x + 100 = n * n, x + 100 + 168 = m * m;步骤2
:由步骤1
推导出:m * m - n * n = (m + n)(m - n) = 168;步骤3
:假设: i = m + n, j = m - n, 则 i * j = 168,由于i和j都是整数,可知i 和 j 至少一个是偶数;步骤4
:由步骤3
推导出: m = (i + j) / 2, n = (i - j) / 2,因为i+j和i-j要可以整除2,所以i 和 j 要么都是偶数,要么都是奇数;步骤5
:从步骤3
和步骤4
推导可知道,i 与 j 均是大于等于 2 的偶数,假如i或j等于1,则另外一个数等于168,和步骤3
冲突,所以,i 与 j 均是大于等于 2 的偶数;步骤6
:由于 i * j = 168, j >= 2(因为j小,所以先设置j的范围),则 1 < i < 168 / 2 + 1。步骤7
:接下来将 i 的所有数字循环计算即可。
3. 实例代码
#include <stdio.h>
int main (void)
{
int i, j, m, n, x;
for (i = 1; i < 168 / 2 + 1; i++)
{
if (0 == 168 % i)
{
j = 168 / i;
if ( (i > j) && ((i + j) % 2 == 0) && ((i - j) % 2 == 0) )
{
m = (i + j) / 2;
n = (i - j) / 2;
x = n * n - 100;
printf ("%d + 100 = %d * %d\t %d + 268 = %d * %d\n", x, n, n, x, m, m);
printf ("x = %d\n", x);
}
}
}
return 0;
}
4. 结果
5. 优化1
由于知道i和j最小是2,并且为偶数,所以for循环可以写成
for (i = 2; i < 168 / 2 + 1; i+=2)
{
}
6. 优化2
根据平方差值规律,可知以下条件:
以下是代码实现:
#include <stdio.h>
#include <math.h>
int main()
{
int n,x,a,m;
double b;
for (n = 1; n <= 168 / 2 ; n++)
{
// 根据 x+100 = n*n可得x = n*n - 100;
x = n*n - 100;
a = x + 268;
b = sqrt(a);
// 如果a开平方后,是整数,则转换类型b和实际b值需相等
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;
}
7. 优化3
由于i*j = 168,i小j大,所以i需小于13.
#include <stdio.h>
int main()
{
int i,j,n,x;
for(i=2; i<13; i++)
{
if(168%i == 0)
{
j = 168/i;
if( i%2==0 && j%2==0 && i<j )
{
n = (i+j)/2;
x = n*n-268;
printf("i=%d,x=%d\n",i,x);
}
}
}
return 0;
}