通过率 0% · 提交 0 · 通过 0
目标检测评估时,需要度量预测框与真值框的重合程度。框用连续坐标 (x1, y1, x2, y2) 表示,宽 = x2 - x1,高 = y2 - y1。两个框的 IoU = 交集面积 / 并集面积;两框只共享一条边或一个点时交集面积为 0,IoU 记为 0。给定 N 个预测框与 M 个真值框,请输出 N×M 的 IoU 矩阵。
这类题属于算法机考高频题型中「华为 AI 岗 / IoU」方向的高频题型,通常考察对「华为 AI 岗 / IoU」的建模能力与边界条件处理。掌握本题的解题思路后,可举一反三应对同类真题方向,稳步提升机考通过率。
第一行输入 N M。接下来 N 行,每行 4 个实数 x1 y1 x2 y2,表示预测框。最后 M 行,每行 4 个实数,表示真值框。
输出 N 行,每行 M 个数,第 i 行第 j 个数是第 i 个预测框与第 j 个真值框的 IoU,按四舍五入保留 4 位小数,用单个空格分隔。
示例 1
输入示例
2 1 0 0 2 2 1 1 3 3 0 0 2 2
输出示例
1.0000 0.1429
两预测框对一真值框
示例 2
输入示例
1 1 0.5 0.5 2.5 1.5 1.0 0.0 3.0 2.0
输出示例
0.3333
一位小数坐标
时间限制 2000 ms · 内存限制 256 MB
本平台为独立第三方培训机构,与华为技术有限公司无任何关联;课程的服务内容与权益以购买协议为准,学习效果因个人情况而异。「华为 OD」「华为可信」等仅为对岗位与考试方向的客观描述,相关商标归各自权利人所有。
这些是真正决定能不能 AC、但通用题解里常被略过的点。
IoU 是目标检测评估与 NMS 的地基,面试手撕和机考都常见。计算本身只有三步:交集、并集、相除,考点全在边界处理——相接、不相交、包含,三类框你都要给出正确的 0 或比值。
两个框 A、B 的交集也是一个矩形(如果存在):
iw = min(Ax2, Bx2) - max(Ax1, Bx1)
ih = min(Ay2, By2) - max(Ay1, By1)
inter = max(0, iw) * max(0, ih)max(0, ·) 这一步是整道题的命门:框不相交时 iw 或 ih 是负数,不钳零的话交集面积会算成正数(负负得正),IoU 直接错。两框只共享一条边时 iw 或 ih 恰好为 0,交集自然为 0,输出 0.0000——这条题面写死了,不用特判。
并集 = 面积A + 面积B − 交集。忘了减交集,重叠部分被算两次,IoU 偏小。包含关系时交集等于小框面积,IoU = 小框/大框,可以拿这个当自查用例。
坐标是至多一位小数的连续值,宽 = x2 − x1(课程第 15 天的约定,没有 +1)。N、M ≤ 200,双层循环 4 万对,毫无压力。输出四舍五入保留 4 位:Python 直接 f"{v:.4f}";注意 0 要输出成 0.0000 而不是 -0.0000(交集为 0 时不会出负,但你如果用了减法路径要留意负零)。
坐标至多一位小数,参考实现读入后乘 10 转成整数运算(面积、交集全程整数),最后再除面积比,规避浮点累积误差;直接用 float 算在这道题的数据范围下也能过,但整数化是更稳的习惯。输出用四舍五入保留 4 位,IoU 落在 [0, 1],不会出现负零。
1. 同一个框和自己:IoU = 1.0000,验证并集公式没把面积算重。 2. 0 0 2 2 和 2 0 4 2(共享一条边):iw = 0,输出 0.0000——相接语义。 3. 大框 0 0 4 4 包含小框 1 1 2 2:IoU = 1/16 = 0.0625——包含时交集是小框整个面积。
N×M 的矩阵输出注意行对应预测框、列对应真值框,别转置。
IoU 是第 15 天检测两件套的前半件,后半件 NMS 直接拿它当子函数——这道题写出来的 iou(a, b) 一个字不改就能用在下一题里。整数化坐标(乘 10)的手法也值得留着:凡是「至多 x 位小数」的题面,都可以放大成整数把浮点误差从根上掐掉。
# IoU = 交集/并集:交集宽高分别 min(右)-max(左),负值与 0 取 max
# 并集 = 面积A + 面积B - 交集;只相接时交集为 0,按 0.0000 输出
import sys
def fmt4(v):
n = int(v * 10000 + 0.5)
return "%d.%04d" % (n // 10000, n % 10000)
def main():
data = sys.stdin.buffer.read().split()
at = 0
n = int(data[at]); at += 1
m = int(data[at]); at += 1
vals = [float(x) for x in data[at:at + 4 * (n + m)]]
pred = [tuple(vals[4 * i:4 * i + 4]) for i in range(n)]
gt = [tuple(vals[4 * (n + i):4 * (n + i) + 4]) for i in range(m)]
lines = []
for p in pred:
pa = (p[2] - p[0]) * (p[3] - p[1])
row = []
for g in gt:
ix = min(p[2], g[2]) - max(p[0], g[0])
if ix < 0.0:
ix = 0.0
iy = min(p[3], g[3]) - max(p[1], g[1])
if iy < 0.0:
iy = 0.0
inter = ix * iy
uni = pa + (g[2] - g[0]) * (g[3] - g[1]) - inter
iou = inter / uni if uni > 0.0 else 0.0
row.append(fmt4(iou))
lines.append(" ".join(row))
sys.stdout.write("\n".join(lines) + "\n")
main()
登录后可查看你在本题的历史提交,以及每次的各用例通过情况。