四平方和
题目描述
四平方和定理,又称为拉格朗日定理:每个正整数都可以表示为至多4个正整数的平方和。
如果把0包括进去,就正好可以表示为4个数的平方和。
比如:
5 = 0^2 + 0^2 + 1^2 + 2^2
7 = 1^2 + 1^2 + 1^2 + 22(符号表示乘方的意思)
对于一个给定的正整数N,可能存在多种平方和的表示法。
要求你对4个数排序:0 <= a <= b <= c <= d
并对所有的可能表示法按 a,b,c,d 为联合主键升序排列,最后输出第一个表示法
输入
输入存在多组测试数据,每组测试数据输入一行为一个正整数N (N<5000000)
输出
对于每组测试数据,要求输出4个非负整数,按从小到大排序,中间用空格分开
样例输入 Copy
5
12
773535
样例输出 Copy
0 0 1 2
0 2 2 2
1 1 267 838
思路:
这题直接用四重for循环遍历所有情况肯定超时。可以只遍历,a,b两个值,然后建立一个数组来判断c2 + b2 =n-a2 -b2 .建立数组f[c2 + d2]=c。 注意由于题目要求n<5000000,n的值较大,数组应定义为全局变量,定义在局部不能声明这么长的数组。
代码:
#include <iostream>
#include <cmath>
using namespace std;
int f[5000001]={0};
int main() {
long long n;
int flag;
/* for(int i=0;i<2200;i++)
f[i]=0;*/
int c,d;
while(scanf("%ld",&n)!=EOF){
//cout<<n<<endl;
for(c=0;c*c*2<=n;c++)
for(d=c; c*c+d*d<=n;d++){
if(f[c*c+d*d]==0){
f[c*c+d*d] = c;
// cout<<c*c+d*d<<' '<<c<<' '<<d<<endl;
}
}
flag=0;
for(int a=0;a*a*4<=n;a++){
for(int b=a;a*a+b*b<=n/2;b++){
//cout<<a<<' '<<b<<endl;
if(f[n-a*a-b*b]!=0){
c=f[n-a*a-b*b];
d=int(sqrt(n-a*a-b*b-c*c)+1e-3);
cout<<a<<' '<<b<<' '<<c<<' '<<d<<' '<<endl;
flag=1;
break;
}
}
if(flag==1){
flag=0;
break;
}
}
}
return 0;
}