LQ0027 四平方和枚举

Posted 海岛Blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LQ0027 四平方和枚举相关的知识,希望对你有一定的参考价值。

题目来源:蓝桥杯2016初赛 C++ A组F题

题目描述
四平方和定理,又称为拉格朗日定理:每个正整数都可以表示为至多4个正整数的平方和。
如果把0包括进去,就正好可以表示为4个数的平方和。
比如:
5 = 0^2 + 0^2 + 1^2 + 2^2
7 = 1^2 + 1^2 + 1^2 + 2^2(^符号表示乘方的意思)
对于一个给定的正整数N,可能存在多种平方和的表示法。
要求你对4个数排序:0 <= a <= b <= c <= d
并对所有的可能表示法按 a,b,c,d 为联合主键升序排列,最后输出第一个表示法

输入格式
输入存在多组测试数据,每组测试数据输入一行为一个正整数N (N<5000000)

输出格式
对于每组测试数据,要求输出4个非负整数,按从小到大排序,中间用空格分开

输入样例
5
12
773535

输出样例
0 0 1 2
0 2 2 2
1 1 267 838

问题分析
方法一:枚举计算是一种方法。为了减少枚举数量,可以采用三重枚举。
方法二:打表,枚举2个数的平方和,也是一种有效的方法。注意,需要选取顺序最小的结果。
方法三:打表c和d,枚举a和b应该是正解。

AC的C语言程序(打表枚举)如下:

/* LQ0027 四平方和 */

#include <stdio.h>
#include <string.h>

#define N 5000000
int C[N + 1], D[N + 1];

void init()

    memset(C, -1, sizeof C);

    for (int c = 0, c2; (c2 = c * c) <= N; c++)
        for (int d = c, b2; c2 + (b2 = d * d) <= N; d++) 
            int t = c2 + b2;
            if (C[t] == -1)
                C[t] = c, D[t] = d;
        


void solve(int n)

    for (int a = 0, a2; (a2 = a * a) <= n; a++)
        for (int b = a, b2; a2 + (b2 = b * b) <= n; b++) 
            int sum = n - (a2 + b2);
            if (C[sum] != -1) 
                printf("%d %d %d %d\\n", a, b, C[sum], D[sum]);
                return;
            
        
    return;


int main()

    init();

    int n;
    while (~scanf("%d", &n))
        solve(n);

    return 0;

AC的C语言程序(枚举2个数的平方和)如下:

/* LQ0027 四平方和 */

#include <stdio.h>
#include <string.h>
#include <math.h>

#define N 5000000
int cnx[N + 1];

void init()

    memset(cnx, -1, sizeof cnx);

    int end = sqrt(N);
    for (int a = 0; a <= end; a++)
        for (int b = a; b <= end; b++) 
            int t = a * a + b * b;
            if (t > N) break;
            if (cnx[t] == -1)
                cnx[t] = a;
        


int main()

    init();

    int n;
    while (~scanf("%d", &n)) 
        int end = n / 2, a = N, b = N, c = N, d = N;
        for (int x = 0; x <= end; x++) 
            if (cnx[x] != -1 && cnx[n - x] != -1) 
                int a2 = cnx[x];
                int b2 = sqrt(x - a2 * a2);
                int c2 = cnx[n - x];
                int d2 = sqrt(n - x - c2 * c2);
                if ((a2 < a) || (a2 == a && b2 < b) || (a2 == a && b2 == b && c2 < c))
                    a = a2, b = b2, c = c2, d = d2;
            
        
        if (a != N)
            printf("%d %d %d %d\\n", a, b, c, d);
    

    return 0;

AC的C语言程序(三重枚举)如下:

/* LQ0027 四平方和 */

#include <stdio.h>
#include <math.h>

#define N 5000000

void solve(int n)

    int end = sqrt(n);
    for (int a = 0; a <= end; a++)
        for (int b = a; b <= end; b++)
            for (int c = b; c <= end; c++) 
                int t = n - a * a - b * b - c * c;
                int d = sqrt(t);
                if (d * d == t) 
                    printf("%d %d %d %d\\n", a, b, c, d);
                    return;
                
            
    return;


int main()

    int n;
    while (~scanf("%d", &n))
        solve(n);

    return 0;

以上是关于LQ0027 四平方和枚举的主要内容,如果未能解决你的问题,请参考以下文章

四平方和

蓝桥杯 四平方和

四平方和(程序设计)

LQ0009 平方十位数枚举

LQ0009 平方十位数枚举

LQ0203 排它平方数枚举+进制