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

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

相关推荐
葡萄成熟时 !7 小时前
JAVA 常用API学习笔记
java·笔记·学习
鹿角片ljp8 小时前
LeetCode 46. 全排列|吃透回溯
算法·leetcode·职场和发展
鼎艺创新科技8 小时前
不依赖 UE/Unity:我们如何从零搭建一套国产三维 GIS 渲染引擎
人工智能·算法·unity·游戏引擎·三维电子沙盘
Rain的Java大神之路8 小时前
介绍一下分布式事务
java·分布式·后端·spring·spring cloud·架构·springcloud
吴声子夜歌9 小时前
Java面试题——基础(一)
java·开发语言
南城以南溫暖如初1479 小时前
外卖CPS实战指南:从技术选型到运营落地全流程解析
java·spring boot·mysql·架构·vue
傻啦嘿哟10 小时前
英雄联盟皮肤爬虫:爬取全皮肤价格与特效,做比价工具
java·c++·爬虫
.道阻且长.11 小时前
11.LeetCode算法习题讲解--滑动窗口--将x减到0的最小操作数
算法·leetcode·职场和发展
码匠许师傅11 小时前
【C++ 面试真题】24. 聊聊 C++ 的时间日期处理
java·c++·面试
wenyq711 小时前
LeetCode 2460. Apply Operations to an Array
算法·leetcode