华为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
压缩后的最简化坐标列表,和输入数据的格式相同。
补充说明
输出的坐标相对顺序不能变化。
四、解题思路
这个问题的核心是找到路径中的关键点,关键点定义为路径中方向发生变化的点。为了找到这些关键点,我们需要遍历路径中的所有点,计算每个点相对于前一个点的方向,并检查是否发生了方向变化。如果发生了方向变化,则记录当前点为关键点。
具体解题步骤如下:
- 初始化变量:
- 读取输入的坐标数组。
- 初始化上一个点的坐标 prevX 和 prevY。
- 初始化上一次的运动方向 prevDirX 和 prevDirY。
- 遍历坐标数组:
- 以步长为2遍历坐标数组,因为每两个元素表示一个点的坐标。
- 获取当前点的坐标 currX 和 currY。
- 计算当前点相对于上一个点的偏移量 deltaX 和 deltaY。
- 计算当前的运动方向 currDirX 和 currDirY,方向的计算是基于偏移量的符号,表示移动的方向(-1、0、1)。
- 比较当前的运动方向和上一次的运动方向,如果发生了变化,则记录上一个点为关键点。
- 记录结果:
- 最后一个点也是关键点,需要记录下来。
- 返回所有关键点的字符串表示。
五、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在线答疑。