问题来源
Timus Online Judge 网站上有这么一道题目:1073. Square Country。这道题目的输入是一个不大于 60,000 的正整数,要求计算出该正整数最少能够使用多少个正整数的平方和来表示。这道题目的时间限制是 1 秒。
问题解答
《数论导引(第5版)》([英]G.H.Hardy、E.M.Wright 著,人民邮电出版社,2008年10月第1版)第 320 页有以下定理:
定理 369(Lagrange 定理): 每个正整数都是四个平方数之和
在这个定理中,平方数是指整数(包括零)的平方。所以,我们有以下 C 语言程序(1073.c):
// http://acm.timus.ru/problem.aspx?space=1&num=1073
#include <stdio.h>
#include <math.h>
int compute(int n)
{
int i, j, k, m = 4;
int i0 = n / 4, i2 = n, j2, k2;
for (i = sqrt(n); i2 > i0; i--)
if ((j2 = n - (i2 = i * i)) == 0) return 1;
else for (j = sqrt(j2); j > 0; j--)
if ((k2 = n - i2 - j * j) == 0) return 2;
else if (k = sqrt(k2), k * k == k2 && m > 3) m = 3;
return m;
}
int main(void)
{
int n;
scanf("%d", &n);
printf("%d", compute(n));
return 0;
}
上述程序中:
- 第 7 行设置 m 的初值为 4,代表一个正整数最多只需要四个平方数就可以表示了。
- 第 9 行开始的主循环决定第一个平方数,如果 n 刚好是平方数(第 10 行),就直接返回 1。
- 第 11 行开始的内循环决定第二个平方数,如果这两个数加起来刚好等于 n (第 12 行),就直接返回 2。
- 第 13 行检查 n 是否可以表示为三个平方数的和,如果是的话,就更新 m 的值为 3 。注意,此时不能直接返回 3,因为可能在后面的循环中发现 n 可以用两个平方数表示。
- 第 14 行返回 m 值(只可能是 3 或者 4)作为最后的答案。
上述程序在 Timus Online Judge 网站的