• 华为OD机试 - 多段线数据压缩(Java 2024 D卷 100分)


    在这里插入图片描述

    华为OD机试 2024D卷题库疯狂收录中,刷题点这里

    专栏导读

    本专栏收录于《华为OD机试(JAVA)真题(D卷+C卷+A卷+B卷)》

    刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。

    一、题目描述

    下图中,每个方块代表一个像素,每个像素用其行号和列号表示。

    在这里插入图片描述

    为简化处理,多段线的走向只能是水平、竖直、斜向45度。

    上图中的多段线可以用下面的坐标串表示:(2,8),(3,7),(3,6),(3,5),(4,4),(5,3),(6,2),(7,3),(8,4),(7,5)。

    但可以发现,这种表示不是最简的,其实只需要存储6个蓝色的关键点即可,它们是线段的起点、拐点、终点,而剩下4个点是冗余的。

    现在,请根据输入的包含有几余数据的多段线坐标列表,输出其最化的结果。

    二、输入描述

    形如2 8 3 7 3 6 3 5 4 4 5 3 6 2 7 3 8 4 7 5

    1、所有数字以空格分隔,每两个数字一组,第一个数字是行号,第二个数字是列号;

    2、行号和列号范围为[0,64),用例输入保证不会越界,考生不必检查;

    3、输入数据至少包含两个坐标点

    三、输出描述

    形如2 8 3 7 3 5 6 2 8 4 7 5

    压缩后的最简化坐标列表,和输入数据的格式相同。

    补充说明

    输出的坐标相对顺序不能变化。

    四、解题思路

    这个问题的核心是找到路径中的关键点,关键点定义为路径中方向发生变化的点。为了找到这些关键点,我们需要遍历路径中的所有点,计算每个点相对于前一个点的方向,并检查是否发生了方向变化。如果发生了方向变化,则记录当前点为关键点。

    具体解题步骤如下:

    1. 初始化变量:
      • 读取输入的坐标数组。
      • 初始化上一个点的坐标 prevX 和 prevY。
      • 初始化上一次的运动方向 prevDirX 和 prevDirY。
    2. 遍历坐标数组:
      • 以步长为2遍历坐标数组,因为每两个元素表示一个点的坐标。
      • 获取当前点的坐标 currX 和 currY。
      • 计算当前点相对于上一个点的偏移量 deltaX 和 deltaY。
      • 计算当前的运动方向 currDirX 和 currDirY,方向的计算是基于偏移量的符号,表示移动的方向(-1、0、1)。
      • 比较当前的运动方向和上一次的运动方向,如果发生了变化,则记录上一个点为关键点。
    3. 记录结果:
      • 最后一个点也是关键点,需要记录下来。
      • 返回所有关键点的字符串表示。

    五、Java算法源码

    public class Test01 {
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            // 读取并解析输入的坐标数组
            int[] coordinates = Arrays.stream(scanner.nextLine().split(" "))
                    .mapToInt(Integer::parseInt).toArray();
            // 输出路径中的关键点
            System.out.println(findKeyPoints(coordinates));
        }
    
        /**
         * 找出路径中的关键点并返回结果
         * @param coordinates 路径的坐标数组
         * @return 关键点的字符串表示
         */
        public static String findKeyPoints(int[] coordinates) {
            StringJoiner result = new StringJoiner(" ");
    
            // 初始化上一个点的坐标
            int prevX = coordinates[0];
            int prevY = coordinates[1];
            // 初始化上一次运动方向
            int prevDirX = 0;
            int prevDirY = 0;
    
            // 遍历坐标数组,步长为2,因为每两个元素表示一个点的坐标
            for (int i = 2; i < coordinates.length; i += 2) {
                int currX = coordinates[i];
                int currY = coordinates[i + 1];
    
                // 计算当前点相对于上一个点的偏移量
                int deltaX = currX - prevX;
                int deltaY = currY - prevY;
    
                // 计算本次运动方向
                int maxDelta = Math.max(Math.abs(deltaX), Math.abs(deltaY));
                int currDirX = deltaX / maxDelta;
                int currDirY = deltaY / maxDelta;
    
                // 如果两次运动的方向不同,则上一个点是拐点,记录下来
                if (currDirX != prevDirX || currDirY != prevDirY) {
                    result.add(prevX + " " + prevY);
                }
    
                // 更新上一个点的坐标和方向
                prevX = currX;
                prevY = currY;
                prevDirX = currDirX;
                prevDirY = currDirY;
            }
    
            // 最后一个点也是关键点,记录下来
            result.add(prevX + " " + prevY);
    
            return result.toString();
        }
    }
    

    六、效果展示

    1、输入

    2 8 3 7 3 6 3 5 4 4 5 3 6 2 7 3 8 4 7 5

    2、输出

    2 8 3 7 3 5 6 2 8 4 7 5

    3、说明

    如上图所示,6个蓝色像素的坐标依次是(2,8)、(3,7)、(3,5)、(6,2)、(8,4)、(7,5)。

    将他们按顺序出即可。

    在这里插入图片描述


    🏆下一篇:华为OD机试 - 简易内存池 - 逻辑分析(Java 2024 C卷 200分)

    🏆本文收录于,华为OD机试(JAVA)真题(D卷+C卷+A卷+B卷)

    刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。

    在这里插入图片描述

  • 相关阅读:
    零数科技CEO林乐受邀出席第九届财新峰会并接受专访
    夯实基础,不能忽视的“数据库”
    微信小程序关联组件
    CV5200无线WiFi通信模组,远距离无线传输方案,助力无线视频传输通信
    C语言,数据在内存中的存储。——保姆级教学
    kafka无法消费数据
    [附源码]计算机毕业设计基于Springboot物品捎带系统
    LeetCode 594. Longest Harmonious Subsequence
    OpenCV 颜色检测| color detection
    一分钟禁用云服务器root用户改用自定义用户
  • 原文地址:https://blog.csdn.net/guorui_java/article/details/139705798