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. 结果

C语言实例_4之平方数计算_算法

5. 优化1

由于知道i和j最小是2,并且为偶数,所以for循环可以写成

for (i = 2; i < 168 / 2 + 1; i+=2)
    {

    }

6. 优化2

根据平方差值规律,可知以下条件:

C语言实例_4之平方数计算_#include_02


以下是代码实现:

#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;
}