暴力做法
时间复杂度:(O(n^3))。
int n;
int main()
{
cin>>n;
for(int i=0;i*i<=n;i++)
for(int j=i;i*i+j*j<=n;j++)
for(int k=j;i*i+j*j+k*k<=n;k++)
{
int t=n-i*i-j*j-k*k;
int d=sqrt(t);
if(d*d == t)
{
cout<<i<<' '<<j<<' '<<k<<' '<<d<<endl;
return 0;
}
}
//system("pause");
return 0;
}
二分做法
枚举(c)和(d),将(c^2+d^2)存至数组中,再枚举(a)和(b),查找(n-a^2-b^2)是否在数组中出现过。时间复杂度:(O(n^2log{n^2})))。
const int N=5e6+10;
struct Node
{
int c,d,sum;
Node(){}
Node(int _c,int _d,int _sum):c(_c),d(_d),sum(_sum){}
bool operator<(const Node &W) const
{
if(sum != W.sum) return sum < W.sum;
if(c != W.c) return c < W.c;
return d < W.d;
}
}cd[N];
int n;
int cnt;
int main()
{
cin>>n;
//枚举c^2+d^2
for(int i=0;i*i<=n;i++)
for(int j=i;i*i+j*j<=n;j++)
{
int sum=i*i+j*j;
cd[cnt++]={i,j,sum};
}
sort(cd,cd+cnt);
bool ok=false;
//枚举a^2+b^2
for(int i=0;i*i<=n;i++)
{
for(int j=i;i*i+j*j<=n;j++)
{
int t=n-i*i-j*j;
int pos=lower_bound(cd,cd+cnt,Node(0,0,t))-cd;
if(pos != cnt && cd[pos].sum == t)
{
cout<<i<<' '<<j<<' '<<cd[pos].c<<' '<<cd[pos].d<<' '<<endl;
ok=true;
break;
}
}
if(ok) break;
}
//system("pause");
return 0;
}
哈希表
时间复杂度:(O(n^2)),但(unordered\_map)常数较大。
unordered_map<int,PII> mp;
int n;
int main()
{
cin>>n;
//枚举c^2+d^2
for(int i=0;i*i<=n;i++)
for(int j=i;i*i+j*j<=n;j++)
{
int sum=i*i+j*j;
if(mp.count(sum) == 0) mp[sum]={i,j};
}
//枚举a^2+b^2
for(int i=0;i*i<=n;i++)
{
for(int j=i;i*i+j*j<=n;j++)
{
int t=n-i*i-j*j;
if(mp.count(t))
{
cout<<i<<' '<<j<<' '<<mp[t].fi<<' '<<mp[t].se<<endl;
return 0;
}
}
}
//system("pause");
return 0;
}