法一:
暴力:不太行
#include<iostream>
using namespace std;
int main()
{
int n;
bool flag=false;
cin>>n;
for(int i=0;i*i<=n;i++)
{
for(int j=i;j*j+i*i<=n;++j)
{
for(int k=j;i*i+j*j+k*k<=n;++k)
{
for(int o=k;o*o+k*k+j*j+i*i<=n;++o)
{
if(i*i+j*j+k*k+o*o==n)
{
cout<<i<<" "<<j<<" "<<k<<" "<<o<<endl;
flag=true;
break;
}
}
if(flag) break;
}
if(flag) break;
}
if(flag) break;
}
return 0;
}
法二:二分
思路:先求出两数的平方和,记录这两个数和他的平方和。再遍历另外两个数,这两个数的平方和为i*i+j*j,那么开始两个数的平方和即为n-i*i-j*j,就在长度为n*n的序列中找出一个sum值为n-i*i-j*j的值,时间复杂度为
(也就是n方logn)
代码
#include<iostream>
#include<algorithm>
using namespace std;
struct Num
{
int c,d,sum;
bool operator<(const Num a)
{
if(sum!=a.sum) return sum<a.sum;
if(c!=a.c) return c<a.c;
return d<a.d;
}
};
Num num[5000005];
int cnt=0;
int main()
{
int n;
bool flag=false;
cin>>n;
for(int i=0;i*i<=n;++i)
{
for(int j=i;i*i+j*j<=n;++j)
{
num[cnt++]=Num{i,j,i*i+j*j};
}
}
sort(num,num+cnt);
for(int i=0;i*i<=n;++i)
{
for(int j=i;j*j+i*i<=n;++j)
{
int t=n-i*i-j*j;
int l=0,r=cnt-1,mid;
while(l<r)
{
mid=(l+r)>>1;
if(t>num[mid].sum) l=mid+1;
else r=mid;
}
if(t==num[l].sum)
{
cout<<i<<" "<<j<<" "<<num[l].c<<" "<<num[l].d<<endl;
flag=true;
break;
}
}
if(flag) break;
}
return 0;
}