四平方和【第七届蓝桥杯省赛C++A/B组,第七届蓝桥杯省赛JAVAB/C组】

四平方和

四平方和定理,又称为拉格朗日定理:

每个正整数都可以表示为至多 4 个正整数的平方和。

如果把 0 包括进去,就正好可以表示为 4 个数的平方和。

比如:

\(5=0^2+0^2+1^2+2^2\)
\(7=1^2+1^2+1^2+2^2\)
对于一个给定的正整数,可能存在多种平方和的表示法。

要求你对 4 个数排序:

\(0≤a≤b≤c≤d\)
并对所有的可能表示法按 a,b,c,d 为联合主键升序排列,最后输出第一个表示法。

输入格式
输入一个正整数 N。

输出格式
输出4个非负整数,按从小到大排序,中间用空格分开。

数据范围
\(0<N<5∗106\)
输入样例:
5
输出样例
0 0 1 2

思路

  1. 暴力
  2. 二分(见二分模板题

Code

1.暴力(11/12 TLE)

点击查看代码
#include<iostream>
#include<cmath>
using namespace std;
int n;

int main(){
	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 t = n - a * a - b * b - c * c;
				int d = sqrt(t);
				//cout << t << "  " << d << endl;
				if(d*d == t && d >= c){
					printf("%d %d %d %d",a,b,c,d);
					return 0;
				}
			}
		}
	}
} 

2. 二分

点击查看代码
#include<iostream>
#include<cstdio>
#include<cmath> 
#include<algorithm>
#define endl '\n'
using namespace std;

const int N = sqrt(5*1e6) + 10;
typedef struct temp{
	int c,d,s;
}temp;
int n;
temp t[N * N];

bool cmp(temp a,temp b){
	if(a.s != b.s)return a.s < b.s;	//二分前的预处理为有序
	else if(a.c != b.c)return a.c < b.c;//维护答案要求的顺序
	else return a.d < b.d;
}
bool check(int mid,int x){
	int c = t[mid].c,d = t[mid].d;
	if(c*c + d*d >= x)return 1;
	else return 0;
}
int main(){
//	ios::sync_with_stdio(false);
//	cin.tie(0),cout.tie(0);
	cin >> n;
	int cnt = 0;
	for(int c = 0; c * c <= n; c ++ ){		//预处理
		for(int d = c; c * c + d * d <= n; d ++){
			t[cnt ++] = {c,d,c * c + d * d};
		} 
	}
	
	sort(t,t + cnt,cmp);
	//for(int i = 0; i < cnt; i ++)printf("%d %d %d\n",t[i].c,t[i].d,t[i].s); 
	for(int a = 0; a * a <= n; a ++ ){	//优化为两层for循环+二分
		for(int b = a; a * a + b * b <= n; b ++ ){
			int x = n - a * a - b * b;	//搜索值
			int l = 0, r = cnt - 1;	//搜索范围
			while(l < r){
				int mid = l + r >> 1;
				if(check(mid,x))r = mid;
				else l = mid + 1;
			}
			int c = t[l].c,d = t[l].d;	//注意这里是l或者r而不是mid 
			if(x == c*c + d*d && b <= c){	//维护答案要求的顺序
				printf("%d %d %d %d",a,b,c,d);	//按格式输出
				return 0;
			}
		}
	}
	return 0;
} 
posted @ 2022-12-16 11:09  Keith-  阅读(16)  评论(0编辑  收藏  举报