四平方和
题目
四平方和定理,又称为拉格朗日定理:
每个正整数都可以表示为至多 4 个正整数的平方和。
如果把 0 包括进去,就正好可以表示为 4 个数的平方和。
比如:
5
=
0
2
+
0
2
+
1
2
+
2
2
5=0^2+0^2+1^2+2^2
5=02+02+12+22
7
=
1
2
+
1
2
+
1
2
+
2
2
7=1^2+1^2+1^2+2^2
7=12+12+12+22
对于一个给定的正整数,可能存在多种平方和的表示法。
要求你对 4 个数排序:
0
≤
a
≤
b
≤
c
≤
d
0≤a≤b≤c≤d
0≤a≤b≤c≤d
并对所有的可能表示法按 a,b,c,d 为联合主键升序排列,最后输出第一个表示法。
输入格式
输入一个正整数 N 。
输出格式
输出4个非负整数,按从小到大排序,中间用空格分开。
数据范围
0 < N < 5 ∗ 1 0 6 0<N<5∗10^6 0<N<5∗106
输入样例
5
输出样例
0 0 1 2
题解一(TLE报错)
思路
- 暴力枚举
#include <iostream>
#include <cmath>
using namespace std;
int main () {
int n;
cin >> n;
for (int a = 0; a * a <= n; a ++)
for (int b = a; a * a + b * b <= n; b ++)
for (int c = b; a * a + b * b + c * c <= n; c ++) {
int d = sqrt(n - a * a - b * b - c * c);
if (d * d == (n - a * a - b * b - c * c)) {
printf("%d %d %d %d", a, b, c, d);
return 0;
}
}
return 0;
}
题解二
思路
- 哈希表存储 c ∗ c + d ∗ d c * c + d * d c∗c+d∗d,时间复杂度 O ( n 2 ) O(n^2) O(n2)
#include <iostream>
#include <cmath>
#include <unordered_map>
using namespace std;
unordered_map<int, pair<int, int>> s;
int main () {
int n;
cin >> n;
for (int c = 0; c * c <= n; c ++)
for (int d = c; c * c + d * d <= n; d ++) {
int t = c * c + d * d;
if (s.count(t) == 0) s[t] = {c, d};
}
for (int a = 0; a * a <= n; a ++)
for (int b = a; a * a + b * b <= n; b ++) {
int t = n - a * a - b * b;
if (s.count(t)) {
printf("%d %d %d %d", a, b, s[t].first, s[t].second);
return 0;
}
}
return 0;
}
题解三
思路
- 二分查找
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 5e6 + 20;
struct S {
int s, c, d;
} sum[N];
bool cmp(struct S &a, struct S &b) {
if (a.s != b.s) return a.s < b.s;
if (a.c != b.c) return a.c < b.c;
return a.d < b.d;
}
int main () {
int n, m = 0;
cin >> n;
for (int c = 0; c * c <= n; c ++)
for (int d = c; c *c + d * d <= n; d ++)
sum[m ++] = {c * c + d * d, c, d};
sort(sum, sum + m, cmp);
for (int a = 0; a * a <= n; a ++)
for (int b = a; a * a + b * b <= n; b ++) {
int t = n - a * a - b * b;
int l = 0, r = m - 1;
while (l < r) {
int mid = l + r >> 1;
if (sum[mid].s >= t) r = mid;
else l = mid + 1;
}
if (sum[l].s == t) {
printf ("%d %d %d %d", a, b, sum[l].c, sum[l].d);
return 0;
}
}
return 0;
}