蓝桥杯-四平方和

本文介绍了一个编程问题,需要将给定的正整数表示为四个非负整数的平方和,并按照a、b、c、d的升序排列输出第一个表示法。通过暴力枚举和计算余数来实现。
摘要由CSDN通过智能技术生成

题目

四平方和定理,又称为拉格朗日定理:
  每个正整数都可以表示为至多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(n<5000000).

输出描述

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

示例:

输入

12

输出 

0 2 2 2

运行限制 

1、最大运行时间:3s

2、最大运行内存:256M

解题思路

    本题需要将一个整数拆为四个非负数的平方和,由于它的数值较小,直接采用暴力枚举的方法就可以。需要注意的是输出条件:对所有的可能表示法按 a,b,c,d 为联合主键升序排列,最后输出第一个表示法。

举个例子:

输入为18时,可得到a.b.c.d的所有可能为:

0 1 1 4
1 2 2 3
0 0 3 3

将 a,b,c,d 联合主键升序排列,为:

0 0 3 3
0 1 1 4
1 2 2 3

 此时应该输出第一个表达式,即0 0 3 3 

代码

#include <iostream>
#include<algorithm>
#include<cmath>
using namespace std;
int a,b,c,d;//保存a、b、c、d的数据
int main()
{
    int n;//输入
    int m1, m2, m3, m4;//保存每选定一个数(a或b或c或d)后,剩余的差
    cin >> n;
    for (; a <= sqrt(n); a++)//a[0]为全局变量,初始化为0
    {//sqrt函数为求根函数
        m1 = n - a * a;
        for (b = 0; b <= sqrt(m1); b++)//每次第一个循环都要将a[1]赋值为0
        {
            m2 = m1 - b * b;
            for (c = 0; c <= sqrt(m2); c++)//每次第二个循环都要将a[2]赋值为0
            {
                m3 = m2 - c * c;
                d = sqrt(m3);//a、b、c确定后,d为定值,故不用枚举
                m4 = m3 - d * d;//由于int类型限制,若m3==3,d==1,m3==4,d==2;
                if (m4 == 0)
                    break;
            }
            if (m4 == 0)
                break;
        }
        if (m4 == 0)
            break;
    }//由于a和b和c都是从0开始循环,那么得出来的数一定为a<=b<=c<=d,且d一定为正整数,故用m4判断循环的截止;
    cout << a << " " << b << " " << c << " " << d;
    return 0;
}

结果

20
0 0 2 4
9
0 0 0 3
599999
1 3 342 695

执行最慢用时:82ms

内存:1672kb

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值