122.四平方和(暴力枚举)

122. 四平方和(暴力枚举)

2016年蓝桥杯省赛 - 四平方和(困难)

标签:2016 省赛 暴力枚举

题目描述

四平方和定理,又称拉格朗日定理:每个正整数都可以表示为至多 4 个正整数的平方和。把 0 也算进去,就正好可以表示为 4 个数的平方和,比如

5=02+02+12+22 5 = 0^2 + 0^2 + 1^2 + 2^2 5=02+02+12+22

7=12+12+12+22 7 = 1^2 + 1^2 + 1^2 + 2^2 7=12+12+12+22

一个正整数可能存在多种表示法。要求把 4 个数排序为 0≤a≤b≤c≤d0 \le a \le b \le c \le d0≤a≤b≤c≤d,并把所有表示法按 a,b,c,da, b, c, da,b,c,d 为联合主键升序排列,输出排在最前面的那一组。

输入描述

一个正整数 NNN(N<5000000N < 5000000N<5000000)。

输出描述

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

输入输出样例

示例 1:

输入

txt 复制代码
5

输出

txt 复制代码
0 0 1 2

示例 2:

输入

txt 复制代码
12

输出

txt 复制代码
0 2 2 2

示例 3:

输入

txt 复制代码
773535

输出

txt 复制代码
1 1 267 838

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 256M

解题思路

四个数要满足 a2+b2+c2+d2=Na^2 + b^2 + c^2 + d^2 = Na2+b2+c2+d2=N,并且 0≤a≤b≤c≤d0 \le a \le b \le c \le d0≤a≤b≤c≤d,输出字典序最小的那一组。

直接四重循环枚举四个数太慢,但注意到:只要 a,b,ca, b, ca,b,c 定了,ddd 也就定了------剩下的部分必须是一个完全平方数。所以先算出

d=⌊N−a2−b2−c2⌋ d = \left\lfloor \sqrt{N - a^2 - b^2 - c^2} \right\rfloor d=⌊N−a2−b2−c2 ⌋

再回头验证 a2+b2+c2+d2=Na^2 + b^2 + c^2 + d^2 = Na2+b2+c2+d2=N 就行。这样四重循环直接降成三重。

把 NNN 看成一条长条就是:a2a^2a2、b2b^2b2、c2c^2c2 之外剩下的那截,必须正好等于 d2d^2d2,否则这组 (a,b,c)(a,b,c)(a,b,c) 作废:

枚举时每一层都从上一个数开始(b≥ab \ge ab≥a、c≥bc \ge bc≥b、d≥cd \ge cd≥c),顺序既不重复也不遗漏;同时用 ⋅\sqrt{\cdot}⋅ 收紧每层的上界,比如给定 aaa 后 bbb 最多取到 N−a2\sqrt{N - a^2}N−a2 ,可以省掉大量不可能的取值。

又因为 a,b,c,da, b, c, da,b,c,d 是从小到大一层层枚举的,第一组满足等式的解,恰好就是按 a,b,c,da, b, c, da,b,c,d 升序排在最前面的那组,找到直接返回即可。

以样例 773535 走一遍:

txt 复制代码
N = 773535

a=0            整个分支试遍,无解
a=1, b=1
  c=1 ... 266    剩余部分都不是完全平方数
  c=267        剩余 = 773535 - 1 - 1 - 267² = 702244
               d = √702244 = 838,且 838 ≥ 267
               → 输出 1 1 267 838

代码实现

python 复制代码
import math


def hs(n):
    am = int(math.sqrt(n))  # a 最大值

    for a in range(am + 1):
        bm = int(math.sqrt(n - a * a))  # 给定a后,b的最大值

        for b in range(a, bm + 1):  # 保证 a <= b
            cm = int(math.sqrt(n - a * a - b * b))  # 给定a和b后,c的最大值

            for c in range(b, cm + 1):  # 保证 b <= c
                t = n - a * a - b * b - c * c  # 剩下的部分应等于 d^2
                d = int(math.sqrt(t))  # 计算d
                if d >= c and a * a + b * b + c * c + d * d == n:
                    return a, b, c, d


n = int(input())

print(' '.join([str(x) for x in hs(n)]))

复杂度分析

  • 时间复杂度 :O(N3/2)O(N^{3/2})O(N3/2),三层枚举 a,b,ca, b, ca,b,c,每层的上界都是 N\sqrt{N}N 级别;找到第一组解就返回,实际往往远小于这个上界。
  • 空间复杂度 :O(1)O(1)O(1),只用了几个循环变量和临时变量。
相关推荐
Pniubi9 小时前
力扣3无重复字符的最长字串(滑动窗口)
算法·leetcode·职场和发展
On The Road :9 小时前
深入理解 JVM 垃圾回收:GC 是什么、如何判定垃圾、四大回收算法全解析
jvm·算法
skywalk81639 小时前
不用 SSH、不装数据库:我用 1 个 Python 脚本 + Git,把 15 个 AI Agent 串成了一条流水线
数据库·人工智能·python·ssh·集群
天天被压力10 小时前
【A股分钟级高频数据完全手册 #02】Python调用股票1分钟数据接口:Pro版最新分时取数与字段解析
java·人工智能·python
天天被压力10 小时前
【A股分钟级高频数据完全手册 #01】Pro版接口体系总览与REST鉴权:42篇地图与从0接入
java·人工智能·python
xyouyuweizhu10 小时前
Java InetAddress 详解:从 IP 地址表示到主机名解析
java·开发语言·python
微尘hjx10 小时前
【Deep-OC-SORT 03】多轨迹算法Deep-OC-SORT-卡尔曼滤波预测过程
算法·yolo·目标跟踪·ultralytics·车跟踪·轨迹算法·deep-oc-sort
老师我太想进步了202612 小时前
【数据结构-3】算法美学之降复杂度
数据结构·算法
机器人零零壹17 小时前
技术白皮书:iRobotCAM如何解决机器人激光切割应用中的核心难点,从CAD离线编程到双目视觉定位与轨迹自适应提升复杂空间曲线切割的精度、效率与柔性化水平
人工智能·算法
belldeep19 小时前
python:genesis-world, Genesis-Embodied-AI
人工智能·python·ai·genesis