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

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

相关推荐
wuminyu1 小时前
专家视角看Java字节码加载与存储指令机制
java·linux·c语言·jvm·c++
MediaTea2 小时前
AI 术语通俗词典:C4.5 算法
人工智能·算法
Navigator_Z2 小时前
LeetCode //C - 1033. Moving Stones Until Consecutive
c语言·算法·leetcode
WBluuue2 小时前
数据结构与算法:莫队(一):普通莫队与带修莫队
c++·算法
callJJ2 小时前
Spring Data Redis 两种编程模型详解:同步 vs 响应式
java·spring boot·redis·python·spring
风筝在晴天搁浅3 小时前
n个六面的骰子,扔一次之后和为k的概率是多少?
算法
wbs_scy3 小时前
Linux线程同步与互斥(三):线程同步深度解析之POSIX 信号量与环形队列生产者消费者模型,从原理到源码彻底吃透
java·开发语言
MATLAB代码顾问4 小时前
Python实现蜂群算法优化TSP问题
开发语言·python·算法
代码飞天4 小时前
机器学习算法和函数整理——助力快速查阅
人工智能·算法·机器学习
jiushiapwojdap4 小时前
LU分解法求解线性方程组Matlab实现
数据结构·其他·算法·matlab