【每日一题】ARC158B - Sum-Product Ratio | 数学 | 中等

题目内容

原题链接

给定一个长度为 n n n 的数组,选择三个下标不同元素 x , y , z x,y,z x,y,z,问 x + y + z x y z \frac{x+y+z}{xyz} xyzx+y+z 的最大值和最小值是多少。

数据范围

  • 1 ≤ n ≤ 2 ⋅ 1 0 5 1\leq n\leq 2\cdot 10^5 1≤n≤2⋅105
  • − 1 0 6 ≤ x i ≤ 1 0 6 , x i ≠ 0 -10^6\leq x_i\leq 10^6,x_i\neq 0 −106≤xi≤106,xi=0

题解

考虑以一个元素为自变量。

x + y + z x y z = x + y x y ⋅ 1 z + 1 x y \frac{x+y+z}{xyz}=\frac{x+y}{xy}\cdot \frac{1}{z}+\frac{1}{xy} xyzx+y+z=xyx+y⋅z1+xy1

这里当 x x x 和 y y y 确定时,极值由 z z z 确定。

显然当 z z z 取极值时,该式子取到极值。

对于 x x x 和 y y y 作为自变量时,也是一样的。

所以考虑取到所有的极值,可以知道的是,两个负数的乘积为正数,所以我们需要考虑到绝对值最小和最大的数,对于正数和负数来说都是最小和最大的三个数。这样至多 12 12 12 个数,三重循环考虑极值即可。

时间复杂度: O ( 1 2 3 ) O(12^3) O(123)

代码

cpp 复制代码
/*
    枚举 i 作为三个数的最中间的,则在前缀和后缀中各找一个数即可
*/

#include <bits/stdc++.h>
using namespace std;

const int MOD = 1e9 + 7;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    cin >> n;

    vector<int> pos, neg;
    for (int i = 0; i < n; ++i) {
        int x; cin >> x;
        if (x > 0) pos.push_back(x);
        else neg.push_back(x);
    }

    sort(pos.begin(), pos.end());
    sort(neg.begin(), neg.end());

    vector<int> arr;
    int m = min(int(pos.size()), 3);
    for (int i = 0; i < m; ++i) arr.push_back(pos[i]);
    m = max(m, int(pos.size()) - 3);
    for (int i = m; i < pos.size(); ++i) arr.push_back(pos[i]);

    m = min(int(neg.size()), 3);
    for (int i = 0; i < m; ++i) arr.push_back(neg[i]);
    m = max(m, int(neg.size()) - 3);
    for (int i = m; i < neg.size(); ++i) arr.push_back(neg[i]);

    double max_ans = 1.0 * (arr[0] + arr[1] + arr[2]) / (1ll * arr[0] * arr[1] * arr[2]);
    double min_ans = max_ans;
    for (int i = 0; i < arr.size(); ++i)
        for (int j = i + 1; j < arr.size(); ++j)
            for (int k = j + 1; k < arr.size(); ++k) {
                double v = 1.0 * (arr[i] + arr[j] + arr[k]) / (1ll * arr[i] * arr[j] * arr[k]);
                max_ans = max(max_ans, v);
                min_ans = min(min_ans, v);
            }

    cout << setprecision(15) << min_ans << "\n" << max_ans << "\n";

    return 0;
}
相关推荐
飞川撸码34 分钟前
【LeetCode 热题100】网格路径类 DP 系列题:不同路径 & 最小路径和(力扣62 / 64 )(Go语言版)
算法·leetcode·golang·动态规划
Neil今天也要学习39 分钟前
永磁同步电机参数辨识算法--IPMSM拓展卡尔曼滤波全参数辨识
单片机·嵌入式硬件·算法
yzx9910132 小时前
基于 Q-Learning 算法和 CNN 的强化学习实现方案
人工智能·算法·cnn
亮亮爱刷题2 小时前
算法练习-回溯
算法
眼镜哥(with glasses)3 小时前
蓝桥杯 国赛2024python(b组)题目(1-3)
数据结构·算法·蓝桥杯
int型码农7 小时前
数据结构第八章(一) 插入排序
c语言·数据结构·算法·排序算法·希尔排序
UFIT7 小时前
NoSQL之redis哨兵
java·前端·算法
喜欢吃燃面7 小时前
C++刷题:日期模拟(1)
c++·学习·算法
SHERlocked937 小时前
CPP 从 0 到 1 完成一个支持 future/promise 的 Windows 异步串口通信库
c++·算法·promise
怀旧,8 小时前
【数据结构】6. 时间与空间复杂度
java·数据结构·算法