P2234 [HNOI2002] 营业额统计 java版本

文章目录

P2234 [HNOI2002] 营业额统计 java版本

题目描述

Tiger 最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。

Tiger 拿出了公司的账本,账本上记录了公司成立以来每天的营业额。分析营业情况是一项相当复杂的工作。由于节假日,大减价或者是其他情况的时候,营业额会出现一定的波动,当然一定的波动是能够接受的,但是在某些时候营业额突变得很高或是很低,这就证明公司此时的经营状况出现了问题。经济管理学上定义了一种最小波动值来衡量这种情况:当最小波动值越大时,就说明营业情况越不稳定。

而分析整个公司的从成立到现在营业情况是否稳定,只需要把每一天的最小波动值加起来就可以了。你的任务就是编写一个程序帮助 Tiger 来计算这一个值。

我们定义,一天的最小波动值 = min ⁡ { ∣ 该天以前某一天的营业额 − 该天营业额 ∣ } \min\{|\text{该天以前某一天的营业额}-\text{该天营业额}|\} min{∣该天以前某一天的营业额−该天营业额∣}。

特别地,第一天的最小波动值为第一天的营业额。

输入格式

第一行为正整数 n n n( n ≤ 32767 n \leq 32767 n≤32767) ,表示该公司从成立一直到现在的天数,接下来的 n n n 行每行有一个整数 a i a_i ai( ∣ a i ∣ ≤ 1 0 6 |a_i| \leq 10^6 ∣ai∣≤106) ,表示第 i i i 天公司的营业额,可能存在负数。

输出格式

输出一个正整数,即每一天最小波动值的和,保证结果小于 2 31 2^{31} 231。

样例 #1

样例输入 #1

复制代码
6
5
1
2
5
4
6

样例输出 #1

复制代码
12

提示

结果说明: 5 + ∣ 1 − 5 ∣ + ∣ 2 − 1 ∣ + ∣ 5 − 5 ∣ + ∣ 4 − 5 ∣ + ∣ 6 − 5 ∣ = 5 + 4 + 1 + 0 + 1 + 1 = 12 5+|1-5|+|2-1|+|5-5|+|4-5|+|6-5|=5+4+1+0+1+1=12 5+∣1−5∣+∣2−1∣+∣5−5∣+∣4−5∣+∣6−5∣=5+4+1+0+1+1=12

算法分析

这个问题可以通过维护一个有序集合来解决。我们使用一个 TreeSet 来存储之前所有天的营业额,以便快速找到与当前天营业额最接近的两个值。

  1. 初始化一个空的 TreeSet 和一个 sum 变量来存储最小波动值的总和。
  2. 对于每一天的营业额,首先检查 TreeSet 是否为空。如果为空,说明是第一天,直接将营业额加到 sum 中。
  3. 如果 TreeSet 不为空,使用 floor 方法找到小于等于当前营业额的最大值,使用 higher 方法找到大于当前营业额的最小值。
  4. 计算当前营业额与这两个值的差的绝对值,并选择最小的差值加到 sum 中。
  5. 将当前营业额添加到 TreeSet 中。

代码实现

java 复制代码
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.StreamTokenizer;
import java.util.TreeSet;

public class Main {
    static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
    static StreamTokenizer st = new StreamTokenizer(in);

    public static void main(String[] args) throws IOException {
        st.nextToken();
        int n = (int) st.nval;
        TreeSet<Integer> set = new TreeSet<>();
        int sum = 0;
        for (int i = 0; i < n; i++) {
            st.nextToken();
            int temp = (int) st.nval;
            if (set.isEmpty()) {
                sum += temp;
            } else {
                Integer a = set.floor(temp);
                Integer b = set.higher(temp);
                if (a == null) {
                    sum += b - temp;
                } else if (b == null) {
                    sum += temp - a;
                } else {
                    sum += Math.min(temp - a, b - temp);
                }
            }
            set.add(temp);
        }
        out.write(Integer.toString(sum));
        out.flush();
    }
}

结语

在本题中,我们使用了 TreeSet 来有效地计算每天的最小波动值。这种方法不仅高效,而且代码简洁易懂。希望这篇文章能帮助你理解如何使用数据结构来解决实际问题。如果你有任何问题或建议,请在下方留言。

版权声明:本博客内容为原创,转载请保留原文链接及作者信息。

相关推荐
躺平大鹅39 分钟前
Java面向对象入门(类与对象,新手秒懂)
java
HXhlx1 小时前
CART决策树基本原理
算法·机器学习
Wect2 小时前
LeetCode 210. 课程表 II 题解:Kahn算法+DFS 双解法精讲
前端·算法·typescript
初次攀爬者2 小时前
RocketMQ在Spring Boot上的基础使用
java·spring boot·rocketmq
花花无缺2 小时前
搞懂@Autowired 与@Resuorce
java·spring boot·后端
颜酱2 小时前
单调队列:滑动窗口极值问题的最优解(通用模板版)
javascript·后端·算法
Derek_Smart3 小时前
从一次 OOM 事故说起:打造生产级的 JVM 健康检查组件
java·jvm·spring boot
NE_STOP4 小时前
MyBatis-mybatis入门与增删改查
java
孟陬7 小时前
国外技术周刊 #1:Paul Graham 重新分享最受欢迎的文章《创作者的品味》、本周被划线最多 YouTube《如何在 19 分钟内学会 AI》、为何我不
java·前端·后端
想用offer打牌7 小时前
一站式了解四种限流算法
java·后端·go