目录

题目

思路

Code


题目

下图中,每个方块代表一个像素,每个像素用其行号和列号表示。为简化处理,多段线的走向只能是水平、竖直、斜向45度。

2024华为od机试C卷【多线段数据压缩】Python 实现华为_2024


编辑

上图中的多段线可以用下面的坐标串表示: (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,5)、(6.2) 、(8,4) 、 (7,5)
现在,请根据输入的包含有几余数据的多段线坐标列表,输出其最简化的结果。

输入描述
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:
输入

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

思路

1:其实这道题考察的是基本的初中数学知识。

2:假设我们只有三个点,我们怎样判断这三个点是否有【起点、拐点、终点】呢?

三个点a,b,c组成线段a-b和线段b-c,两个线段的斜率不一致,那么这三个点肯定就不存在拐点,也就可以消掉b这个点。

3:具体我们实现的时候可以不使用斜率,而可以使用向量乘积这个特性。

2024华为od机试C卷【多线段数据压缩】Python 实现华为_2024_02


编辑

4:其实这个题目也是和这个题目很像。 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

编辑

Code

# coding:utf-8
#JSRUN引擎2.0,支持多达30种语言在线运行,全仿真在线交互输入输出。 
import functools
import sys
from collections import Counter, defaultdict
import copy
from itertools import permutations
import re
import math
import sys
from queue import Queue
 
def checkStraightLine(point1, point2, point3):
    y1 = point2[1] -point1[1]
    x1 = point2[0] -point1[0]
    y2 = point3[1] -point2[1]         
    x2 = point3[0] -point2[0]
    if (y1*x2 != y2*x1):
        return False
    return True

nums = [int(x) for x in input().split(" ")]
result = []
result.append(nums[0])
result.append(nums[1])
for i in range(2, len(nums)-2, 2):
    if (not checkStraightLine([nums[i-2], nums[i-1]], 
                        [nums[i], nums[i+1]], 
                        [nums[i+2], nums[i+3]])) :
        result.append(nums[i])
        result.append(nums[i+1])

if(len(nums)>=4):
    result.append(nums[-2])
    result.append(nums[-1])


output_path = ""
for i in range(len(result)):
    output_path += str(result[i])
    if (i != len(result) - 1) :
        output_path += " "
print(output_path)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.