【信息奥赛题解】四平方和(详细分析题解 & C++ 代码)

这篇具有很好参考价值的文章主要介绍了【信息奥赛题解】四平方和(详细分析题解 & C++ 代码)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

📚 四平方和

摊主的个人技术博客:https://rickyxcoder.top/ 🧑🏻‍💻
备用站点:https://rickyxcoder.gitee.io/

🚀 题目浏览

【题目名称】四平方和
【题目描述】

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

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

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

比如:

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

对于一个给定的正整数,可能存在多种平方和的表示法。

要求你对 4 4 4 个数排序:

0 ≤ a ≤ b ≤ c ≤ d 0 \le a \le b \le c \le d 0abcd

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

【输入】

输入一个正整数 N N N

【输出】

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

【数据范围】

0 < N < 5 ∗ 1 0 6 0 \lt N \lt 5∗10^6 0<N<5106

【输入样例】
5
【输出样例】
0 0 1 2
【原题链接】

https://www.luogu.com.cn/problem/P8635


☘️ 题解分析

四重循环的暴力枚举做法,显然会 TLE,所以可以采用 哈希 的方法,来降低时间复杂度。

正确思路

  • c c c d d d 的平方和存储到自己模拟的哈希表中,该步复杂度为 O ( n ) ∗ O ( n ) = O ( n ) O(\sqrt n) * O(\sqrt n) = O(n) O(n )O(n )=O(n)
  • 枚举 a , b a,b ab,并且在哈希表中查找 n − a ∗ a − b ∗ b n - a * a - b * b naabb,该步复杂度为 ( O n ) ∗ O ( n ) ∗ O ( 1 ) = O ( n ) (O\sqrt n) * O(\sqrt n) * O(1) = O(n) (On )O(n )O(1)=O(n)

所以该思路的时间复杂度为 O ( n ) + O ( n ) = O ( n ) O(n) + O(n) = O(n) O(n)+O(n)=O(n),满足该题的数据范围。

本题推荐使用自己 用数组模拟的哈希表(相较于 STL 会更加快)


🧑🏻‍💻 C++ 代码

#include<bits/stdc++.h>

using namespace std;
const int N = 5e6 + 10;

int n;
int C[N], D[N];  // 哈希表,C[k]存储平方和为k时,c的值;D[k]存储平方和为k时,d的值

int main() {
    cin >> n;

    // 将c、d的平方和存入哈希表(复杂度为O(N)))
    memset(C, -1, sizeof(C)); // 初始化为-1,因为0是有实际含义的
    memset(D, -1, sizeof(D));
    for (int c = 0; c * c <= n; c++) {
        for (int d = c; c * c + d * d <= n; d++) {
            int sum = c * c + d * d;
            if (C[sum] == -1)  // 该总和第一次出现,记录此时c和d的值
                C[sum] = c, D[sum] = d;
        }
    }

    // 枚举a,b,查找 n - a*a - b*b 的哈希值
    // 哈希值存在,说明此时a,b,c,d平方和为n
    // 复杂度是sqrt(n) * sqrt(n) * O(1)= O(n) 哈希表查找为O(1)
    for (int a = 0; a * a <= n; a++) {
        for (int b = a; a * a + b * b <= n; b++) {
            int dis = n - a * a - b * b;
            if (C[dis] > -1) {
                cout << a << " " << b << " " << C[dis] << " " << D[dis] << endl;
                return 0;  // 下面没有更多需求的话,直接return 0结束即可,不用写goto
            }
        }
    }

    return 0;
}

✍️ 写在最后

如果小伙伴们觉得博主写的不错,可以给文章点个赞,让优质的文章有更大的概率出现在搜索榜单的前面,为未来的小伙伴们节约更多搜索、阅读的成本。

同时你的支持也是我不断创作的动力。😃

有想要看更多题解报告的小伙伴,也可以关注我的专栏「信息奥赛题解」。

我们下期再见。👋文章来源地址https://www.toymoban.com/news/detail-407605.html


到了这里,关于【信息奥赛题解】四平方和(详细分析题解 & C++ 代码)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 模型评估(误差平方和(SSE The sum of squares due to error))

    模型评估(误差平方和(SSE The sum of squares due to error))

    举例:(下图中数据-0.2, 0.4, -0.8, 1.3, -0.7, 均为真实值和预测值的差) 在k-means中的应用: 公式各部分内容: 上图中: k=2 SSE图最终的结果,对图松散度的衡量. (eg:  SSE(左图)SSE(右图) ) SSE随着聚类迭代,其值会越来越小,直到最后趋于稳定: 如果质心的初始值选择不好,SSE只会达到一个不怎

    2024年02月04日
    浏览(6)
  • MATLAB知识点: SSE: 误差平方和、 MSE: 均方误差、RMSE: 均方根误差、MAE: 平均绝对误差、MAPE: 平均绝对百分比误差、SMAPE: 对称平均绝对百分比误差、R方: 决定系数

    MATLAB知识点: SSE: 误差平方和、 MSE: 均方误差、RMSE: 均方根误差、MAE: 平均绝对误差、MAPE: 平均绝对百分比误差、SMAPE: 对称平均绝对百分比误差、R方: 决定系数

    ​讲解视频:可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。​ MATLAB教程新手入门篇(数学建模清风主讲,适合零基础同学观看)_哔哩哔哩_bilibili 节选自第3章 3.4.2 算术运算 学完了矩阵的算术运算后,我们来做一些练习。 假设真实值是向量 ,拟合值或

    2024年02月21日
    浏览(9)
  • 信息学奥赛一本通(基础算法与数据结构-题解汇总目录)

    信息学奥赛一本通(C++版)在线评测系统 基础(二)基础算法   更新中。。。。。。 第一章高精度计算 1307【例1.3】高精度乘法 1308【例1.5】高精除 1309【例1.6】回文数(Noip1999) 1168大整数加法 1169大整数减法 1170计算2的N次方 1171大整数的因子 1172求10000以内n的阶乘 1173阶乘

    2024年02月16日
    浏览(10)
  • C++信息学奥赛1119:矩阵交换行

    C++信息学奥赛1119:矩阵交换行

    解题思路:当输出时换行 解题程序:

    2024年02月04日
    浏览(5)
  • C++信息学奥赛1201:菲波那契数列

    C++信息学奥赛1201:菲波那契数列

    代码逻辑:首先输入一个整数n,然后输入n个整数,并将它们存入一个数组arr中。对于每个输入的整数x,通过递归调用f(x)来计算其对应的斐波那契数列值,将得到的结果存入另一个数组brr中。最后,输出数组brr的所有元素。

    2024年02月07日
    浏览(5)
  • C++信息学奥赛1121:计算矩阵边缘元素之和

    C++信息学奥赛1121:计算矩阵边缘元素之和

    题解:i 0 or j 0 or i n-1 or j m-1 or i n-1 or j m-1 代码:

    2024年02月11日
    浏览(8)
  • C++信息学奥赛1170:计算2的N次方

    C++信息学奥赛1170:计算2的N次方

    该程序的逻辑如下: 首先,从标准输入读取一个整数n。 创建一个大小为100的整型数组arr,并用-1进行初始化。 将arr数组的第一个元素设置为1。 使用变量j来追踪数组arr的索引。 使用循环结构,重复n次以下步骤: 将j重置为0。 使用while循环,将数组arr中的每个元素乘以2,直

    2024年02月09日
    浏览(7)
  • c++ 信息学奥赛 2047:【例5.16】过滤空格

    c++ 信息学奥赛 2047:【例5.16】过滤空格

    解析:本题中使用一个技巧,那就是scanf函数在读取数据时,不读取空格。当遇到空格时就停止了。 以下是一些关于 scanf 函数的重要信息: scanf 函数的原型如下: int scanf(const char *format, ...); 它返回成功读取的项目数。 format 参数是一个格式字符串,用于指定要读取的数据类

    2024年02月05日
    浏览(9)
  • C++信息学奥赛1186:出现次数超过一半的数

    C++信息学奥赛1186:出现次数超过一半的数

    这段代码的作用是判断给定的整数数组中是否存在出现次数超过一半的元素。首先,通过循环输入整数数组的元素。然后,通过两层循环遍历数组,外层循环逐个元素进行统计,内层循环计算当前元素在数组中出现的次数。在内部循环中,如果发现有元素出现次数超过了数组

    2024年02月10日
    浏览(8)
  • 信息学奥赛一本通(C++版)OJ:2023题【例4.8】数据统计

    时间限制: 1000 ms 内存限制: 65536 KB 提交数: 41259 通过数: 16741 【题目描述】 输入一些整数,求出它们的最小值、最大值和平均值(保留3位小数)。输入保证这些数都是不超过1000的整数。 【输入】 一行,若干个整数。 【输出】 一行,即,最小值、最大值和平均值(保留3位小

    2024年02月12日
    浏览(11)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包