(二分)(结构体)(多关键字排序)1221. 四平方和

简介: (二分)(结构体)(多关键字排序)1221. 四平方和

题目链接

1221. 四平方和 - AcWing题库


一些话

切入点

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

// 要求你对 4个数排序:0≤a≤b≤c≤d

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

//0<N<5∗106,


// 输出满足性质的情况,这符合枚举的前提条件,

// 只看范围枚举可能超时,但实际上因为是算平方和还有0≤a≤b≤c≤d这个条件,枚举的情况有很多可以被剪去,实际的时间

// 是可以支持三重暴力枚举的(也可能是数据太弱了)

// 选择暴力还是有不小的风险,此题最保险的做法是用二分


流程

// 先枚举c,d得到平方和,把结果存起来(平方和与字母)(也可以枚举a,b)(但后面的c,d枚举要稍微修改)


三元组且要排序,就很容易想到用结构体存


重载>运算符,按平方和->c ->d的顺序排序后,再枚举另外两个字母,

// 用n减去这个平方和,然后二分查找结构体里有没有存和这个结果相同的数据,有的话就缩小右边界,找到最左的下标.

//最后输出当前枚举的a,b,和下标对应的结构体里存的c,d


套路

结构体重载运算符实现多关键字排序

struct Sum{
    int s,c,d;
    bool operator<(Sum & t){
        if(s != t.s) return s < t.s;
        if(c != t.c) return c < t.c;
        return d < t.d;
    }
}sum[N];

ac代码

// 14:35-15:53wa
// 16:14~29ac
// 16:30 ~ 16:40ac
// 如果把 0包括进去,就正好可以表示为 4个数的平方和。
// 要求你对 4个数排序:0≤a≤b≤c≤d
//并对所有的可能表示法按  a,b,c,d为联合主键升序排列最后输出第一个表示法。
// 输出满足性质的情况,这符合枚举的前提条件,0<N<5∗106,
// 只看范围枚举可能超时,但实际上因为是算平方和还有0≤a≤b≤c≤d这个条件,枚举的情况有很多可以被剪去,实际的时间
// 是可以支持三重暴力枚举的(也可能是数据太弱了)
// 选择暴力还是有不小的风险,此题最保险的做法是用二分
// 先枚举两个字母得到平方和,把结果存起来(平方和与字母)按平方和-》c -》d的顺序排序后,再枚举另外两个字母,
// 用n减去这个平方和,然后二分查找结构体里有没有存和这个结果相同的数据,有的话就缩小右边界,找到最左的下标.
//最后输出当前枚举的a,b,和下标对应的结构体里存的c,d
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
const int N = 5e6 + 10;
struct Sum{
    int s,c,d;
    bool operator<(Sum & t){
        if(s != t.s) return s < t.s;
        if(c != t.c) return c < t.c;
        return d < t.d;
    }
}sum[N];
int main(){
    int n,k = 0;
    cin >> n;
    for(int c = 0;c * c <= n;c++){
        for(int d = c;d * d + c * c <= n;d++){
            sum[k++] = {c * c + d * d,c,d};
        }
    }
    sort(sum,sum+k);
    for(int a = 0;a * a <= n;a++){
        for(int b = a;b * b + a * a <= n;b++){
            int t = n - a * a - b * b;
            int l = 0,r = k;
            while(l < r){
                int mid = l + r >> 1;
                if(sum[mid].s >= t) r = mid;
                else l = mid + 1;
            }
            if(sum[l].s == t){
                cout << a << " " << b << " " << sum[l].c << " " << sum[l].d << endl;
                return 0;
            }
        }
    }
}
目录
打赏
0
0
0
0
0
分享
相关文章
|
11月前
|
如何判断一个数是质数? 要求:编写一个Python函数,输入一个整数,输出该整数是否为质数。质数是指大于1的自然数中,除了1和它本身以外不再有其他因数的数。
如何判断一个数是质数? 要求:编写一个Python函数,输入一个整数,输出该整数是否为质数。质数是指大于1的自然数中,除了1和它本身以外不再有其他因数的数。
464 1
|
11月前
DAY-4 | 力扣 - 求自身以外数组的乘积:区间划分,左右累乘,巧求乘积
该文档是关于LeetCode上的一道题目“Product of Array Except Self”的题解。提供了两种解题方法,一是暴力破解,即计算所有数的乘积后再逐个除以当前元素;二是左右累乘法,通过两次遍历数组分别计算左侧和右侧元素的乘积,避免了除法操作。其中,左右累乘法更优,代码实现中展示了这种方法。
75 1
【动态规划 区间dp 位运算】3117. 划分数组得到最小的值之和
【动态规划 区间dp 位运算】3117. 划分数组得到最小的值之和
【动态规划 区间dp 位运算】3117. 划分数组得到最小的值之和
|
11月前
|
简记二分算法模板与代码案例:整数二分和浮点数二分
本文介绍了两种算法模板,分别是整数二分和浮点数二分。
86 0
|
11月前
力扣421. 数组中两个数的最大异或值(字典树)
力扣421. 数组中两个数的最大异或值(字典树)
|
11月前
|
【汇编语言实战】求两组给定数组最大值
【汇编语言实战】求两组给定数组最大值
28 0
信息学奥赛 如何在整数数组中寻找两数之和等于给定目标值
本文介绍了在整数数组中寻找两个数之和等于给定目标值的问题,提供了两种解法:暴力法和哈希表法。通过比较两种解法的时间复杂度,指出了哈希表法更为高效。
169 0
二维数组实验题:按如下公式递归计算矩阵行列式的值:(C语言)
二维数组实验题:按如下公式递归计算矩阵行列式的值:(C语言)
263 1
二维数组实验题:按如下公式递归计算矩阵行列式的值:(C语言)
数据结构与算法面试题:给定非负整数 m 和 n,计算不大于 m 的数字中,素数的个数。(提示:算法原理为埃氏筛、线性筛)
数据结构与算法面试题:给定非负整数 m 和 n,计算不大于 m 的数字中,素数的个数。(提示:算法原理为埃氏筛、线性筛)
124 0