1.【问题描述】第四平方和定理,又称为拉格朗日定理:
每个正整数都可以表示为至多4个正整数的平方和。
如果把0包括进去,就正好可以表示为4个数的平方和。
比如:5 = 0^2 +0^2 + 1^2 + 2^2 = 1^2 + 1^2 + 1^2 + 2^2
(^符号表示乘方的意思)对于一个给定的正整数,可能存在多种平方和的表示法。
要求你对4个数排序: 0 <= a <= b <= c <= d
并对所有的可能表示法按 a,b,c,d 为联合主键升序排列,最后输出第一个表示法
【输入】 一个正整数N (N<5000000)
【输出】 4个非负整数,按从小到大排序,中间用空格分开
【输入范例1】 5 【输出范例1】0 0 1 2
【输入范例2】773535【输出范例2】1 1 267 838
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define Max 5000000
int m[Max] = {
0}; //若m[i] = 1 ;则表示i能用两个完全平方数相加而得 ; (别人的想法)
int fn (int N) //fn为常规思路,穷举法:
{
int a, b, c, d ;
for ( a=0; pow(a,2)<=N; a++)
{
for ( b=0; pow(a,2)+pow(b,2)<=N; b++)
{
for ( c=0; pow(a,2)+pow(b,2)+pow(c,2)<=N; c++)
{
for ( d=0; pow(a,2)+pow(b,2)+pow(c,2)+pow(d,2)<=N; d++)
{
if ( pow(a,2)+pow(b,2)+pow(c,2)+pow(d,2)==N)
{
printf("%d %d %d %d\n",a,b,c,d) ;
return 0;
}
}
}
}
}
}
void init (int N)
{
int i, j ;
for ( i=0; pow(i,2)<=N; i++)
{
for ( j=0; pow(j,2)<=N; j++)
{
if (pow(i,2)+pow(j,2)<=N)
m[i*i+j*j] = 1 ; //这里不能使用m[pow(i,2)+pow(j,2)] ;不然会报错,不知道为啥....
}
}
}
int fn1(int N)
{
int a, b, c, d ;
for ( a=0; a*a<=N; a++)
{
for ( b=0; b*b<=N; b++)
{
if ( m[N-a*a-b*b] == 0) continue ;
for ( c=0; c*c<=N; c++)
{
d = N-a*a-b*b-c*c ;
double l = sqrt(double(d)) ; //判断l是否为正整数
if ( l==int(l)) //会自动隐形转换,相当于if( l==double(int(l))) ;
{
printf("%d %d %d %d",a,b,c,int(l)) ;
return 0 ;
}
}
}
}
}
int main()
{
int N = 0 ;
scanf("%d",&N) ;
fn (N) ;
init (N) ;
fn1(N) ;
}