OD C卷 - 多线段数据压缩

多段 线 数据压缩 (200)

  • 如图中每个方格为一个像素(i,j),线的走向只能水平、垂直、倾斜45度;
  • 图中线段表示为(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), 分别为起点、拐点、终点
  • 根据输入的线段数据,输出简化的结果
    在这里插入图片描述

输入描述:
2 8 3 7 3 6 3 5 4 4 5 3 6 2 7 3 8 4 7 5
每两个一组(i, j) i,j 范围为【0,64】
输入至少包含两个坐标点
输出描述:
2 8 3 7 3 5 6 2 8 4 7 5

思路:

  • 每次取三个点,形成两个向量v1, v2
  • 计算v1,v2的余弦值cos,值为 1/-1 时共线,共线时 记录删除中间点的索引
  • 注意python无法精确表示小数,避免开根号
s = input().strip()
n = len(s)

# 字符串转为点
points = []
remove_points = []
for i in range(0, n, 4):
    points.append(list(map(int, s[i:i+4].strip().split())))


def inline(v1, v2):
    a = 0
    v1_sum = 0
    v2_sum = 0
    # 计算内积
    for j in range(2):
        a += v1[j] * v2[j]
        v1_sum += v1[j]**2
        v2_sum += v2[j]**2

    b = v1_sum * v2_sum # 开根号 无法精确表示小数,所有分子分母均平方
    if a**2 == b:  # 余弦值为1,夹角为0 或者180  共线
        return True

    return False


#
# [[2, 8], [3, 7], [3, 6], [3, 5], [4, 4], [5, 3], [6, 2], [7, 3], [8, 4], [7, 5]]
point_num = len(points)
for i in range(point_num-2): # 每次取三个点,形成两个向量,计算是否共线 (只需关心是否为拐点)
    v1 = [points[i][0]-points[i+1][0], points[i][1]-points[i+1][1]]
    v2 = [points[i+1][0]-points[i+2][0], points[i+1][1]-points[i+2][1]]
    if inline(v1, v2): # 如果共线,则记录删除中间点 即 i+1 位置
        remove_points.append(i+1)


print("删除点", remove_points)

# 遍历所有的坐标点
out_str = ""
for j in range(point_num):
    if j not in remove_points:
        s, e = points[j]
        out_str += str(s) + " " + str(e) + " "

print(out_str.strip())
  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

laufing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值