蓝桥杯-四平方和

news/发布时间2024/5/19 14:03:09

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

每个正整数都可以表示为至多 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。

输出格式

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

数据范围

0<N<5∗1e6

输入样例:

5

输出样例:

0 0 1 2

题解:

暴力three重循环判断会超时~

  • 枚举 c 和 d 的所有可能, 并把 c, d, c * c + d * d 都存到数组中
  • 对数组排序。 (从大到小, 从小到达都行, 但对应的二分不一样)
  • 枚举 a 和 b 的所有可能, 用二分找 当前 a b 下, 对应的 c d, 判断是否满足 n = a * a + b * b + c * c + d * d, 满足的话输出并退出ok了
#include <bits/stdc++.h>
using namespace std;
const int N = 1e7 + 10;
struct Node {int c, d, sum;
};
Node v[N];
bool cmp(Node a, Node b)
{if (a.sum != b.sum) return a.sum < b.sum;if (a.c != b.c) return a.c < b.c;return a.d < b.d;
}int main()
{int n, m = 0; cin >> n;for (int i = 0; i * i <= n; i ++)for (int j = i; i * i + j * j <= n; j ++)v[m ++] = {i, j, i * i + j * j};sort(v, v + m, cmp);  // 从小到大排序for (int i = 0; i * i <= n; i ++)for (int j = 0; j * j + i * i <= n; j ++)  // a b 要从 0 开始枚举, 题中要求a≤b≤c≤d{int l = 0, r = m - 1;int t = n - i * i - j * j;while (l < r){int mid = l + r >> 1;if (v[mid].sum >= t) r = mid;  // 二分, 相同的v[mid].sum, 查找的是第一个满足的, 由于我们是 升序, 刚好满足 c <= delse l = mid + 1;}if (v[l].sum == t){cout << i << ' ' << j << ' ' << v[l].c << ' ' << v[l].d << endl;return 0;}}return 0;
}

觉得写的不错的话, 点个赞吧~




下面不是题解, 是笔者为了让自己更好理解二分写的笔记

  • 对比上面的代码可以发现 代码中有 "<--------" 注释的是发生改变的
  • 其中 if (v[mid].sum <= t), 二分条件发生变化, 导致了 这个二分在 v[mid].sum 相同的情况下, 找到的是 最后一个 符合条件的 下标
  • 上面的代码在 v[mid].sum 相同的情况下, 找到的是 第一个 符合条件的 下标
  • so 在下面代码排序中我们是让 c 和 d 按照倒序的方法排的顺序
#include <bits/stdc++.h>
using namespace std;
const int N = 1e7 + 10;
struct Node {int c, d, sum;
};
Node v[N];
bool cmp(Node a, Node b)
{if (a.sum != b.sum) return a.sum < b.sum;if (a.c != b.c) return a.c > b.c;  // <------return a.d > b.d;       // <-------
}int main()
{int n, m = 0; cin >> n;for (int i = 0; i * i <= n; i ++)for (int j = i; i * i + j * j <= n; j ++)v[m ++] = {i, j, i * i + j * j};sort(v, v + m, cmp);for (int i = 0; i * i <= n; i ++)for (int j = 0; j * j + i * i <= n; j ++){int l = 0, r = m - 1;int t = n - i * i - j * j;while (l < r){int mid = l + r + 1 >> 1;if (v[mid].sum <= t) l = mid;   // <-------else r = mid - 1;   // <-------}if (v[l].sum == t){cout << i << ' ' << j << ' ' << v[l].c << ' ' << v[l].d << endl;return 0;}}return 0;
}

口诀
if 后面是 r 的话 找到的是 l 的, 即 是 第一个 满足条件的
if 后面是 l 的话 找到的是 r 的, 即 是 最后一个 满足条件的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ulsteruni.cn/article/24423067.html

如若内容造成侵权/违法违规/事实不符,请联系编程大学网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

02_Modbus的功能码与报文详解

Modbus协议类型 Modbus从站四张表类型 主站常用功能码 Modbus TCP请求报文,功能码03Modbus TCP应答报文,功能码03 00 17为23个字节:请求长度加应答长度06+17=23; 14为20长度:14+06=20Modbus UDP请求报文,功能码03Modbus UDP应答报文,功能码03 Modbus RTU请求报文,功能…

https加密机制

参考:https://www.cnblogs.com/sxiszero/p/11133747.html 对称加密:只用一个秘钥的加解密,如果秘钥进行了泄漏,导致数据不安全 非对称加密:非对称加密算法需要一组密钥对,分别是公钥和私钥,这两个密钥是成对出现的。公钥加密的内容需要对应的私钥解密,私钥加密的内容需…

Docker-DevOps-入门手册(全)

Docker DevOps 入门手册(全)原文:zh.annas-archive.org/md5/A074DB026A63DFD63D361454222593A5 译者:飞龙 协议:CC BY-NC-SA 4.0前言 Docker 与 DevOps 概述了容器化的强大力量以及这种创新对开发团队和一般运营的影响。我们还将了解 DevOps 的真正含义,涉及的原则,以及…

locust压测

目录locust1.依赖2. 实例2.1 压测方式2.2 locust服务端2.3 待压测接口服务3. 参考文档 locust 1.依赖 pip install locust2. 实例 2.1 压测方式 1. 压测方式 1.1 前台自编辑方式修改文件名为locustfile.py 并在控制台使用locust启动前台服务 用户自定义压测参数并开启压测1.2 …

linux系统CentOS下安装snmp服务

使用yum安装1.直接使用yum安装snmp*yum install -y net-snmp net-snmp-utils*2.可能碰到的报错3.按照提示安装依赖*yum install libmysqlclient.so.18* 4.要是还有报错,就按照提示执行*yum install -y net-snmp net-snmp-utils --skip-broken*5.其他安装好的上面是四个包,缺…

SQL

-一、名词 DB(DataBase):数据库 DBMS(DataBase Management System):数据库管理系统 SQL(Structured Query Language):一种操作关系型数据库的编程语言 二、安装: https://dev.mysql.com/downloads/windows/installer/8.0.html 选择MySQL Community Downloads -> M…