T1四平方和:(二分)
//二分写法
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#define N 5000010
using namespace std;
struct sum{
int s,c,d;
bool operator< (const sum &t) const{
if(s!=t.s)
return s<t.s;
if(c!=t.c)
return c<t.c;
return d<t.d;
}
}S[N];
int n,m;
int main()
{
cin>>n;
for(int c=0;c*c<=n;c++)
{
for(int d=c;d*d+c*c<=n;d++)
{
S[m++]={c*c+d*d,c,d};//暂存可行的cd方案
}
}
sort(S,S+m);
for(int a=0;a*a<=n;a++)
{
for(int b=a;b*b+a*a<=n;b++)
{
int t=n-a*a-b*b;
int l=0,r=m-1;
while(l<r)//模板1
{//找最大的,所以我们要在[l,mid]取到mid
int mid=l+r>>1;
if(S[mid].s>=t)
r=mid;
else
l=mid+1;
}
if(S[l].s==t)
{
cout<<a<<" "<<b<<" "<<S[l].c<<" "<<S[l].d<<endl;
return 0;
}
}
}
return 0;
}
哈希写法:
#include<stdio.h>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<tr1/unordered_map>
#define x first
#define y second
#define N 2500010
using namespace std;
using namespace std::tr1;
typedef pair<int,int> PII;
int n,m;
unordered_map<int,PII > s;//哈希表存,可以不存重复的
int main()
{
cin>>n;
for(int c=0;c*c<=n;c++)
{
for(int d=c;d*d+c*c<=n;d++)
{
int t=c*c+d*d;
if(s.count(t)==0)//没存过的话
s[t]={c,d};//凑成这个和t的两个数就是c,d字典序最小
}
}
for(int a=0;a*a<=n;a++)
{
for(int b=a;b*b+a*a<=n;b++)
{
int t=n-a*a-b*b;
if(s.count(t))
{
cout<<a<<" "<<b<<" "<<s[t].x<<" "<<s[t].y<<endl;
return 0;
}
}
}
return 0;
}