通过率 100% · 提交 1 · 通过 1
这道 OJ 的配套动画
线性回归与批量梯度下降 · 对应本题的思路、过程和代码
使用训练集的列最小值和最大值完成 Min-Max 归一化,再从零参数开始执行固定轮数的批量梯度下降,最后预测查询样本。常量特征归一化为 0,查询值不做区间截断。
这类题属于算法机考高频题型中「华为 AI 岗 / 线性回归」方向的高频题型,通常考察对「华为 AI 岗 / 线性回归」的建模能力与边界条件处理。掌握本题的解题思路后,可举一反三应对同类真题方向,稳步提升机考通过率。
第一行输入 n d m e,第二行输入学习率 eta。接下来 n 行包含 d 个整数特征和一个实数标签,随后 m 行包含 d 个整数特征。
输出 m 行,每行一个保留四位小数的预测值;绝对值小于 0.00005 时输出 0.0000。
1 <= n <= 500;1 <= d <= 8;1 <= m <= 200;0 <= e <= 200;0 <= eta <= 0.2;整数特征绝对值不超过 10000,标签绝对值不超过 10000。
示例 1
输入示例
2 1 2 1 0.1 0 1 10 3 0 10
输出示例
0.4000 0.7000
一轮批量更新后 b=0.4,w=0.3。
示例 2
输入示例
2 2 1 0 0.2 0 0 5 10 20 9 5 10
输出示例
0.0000
训练轮数为 0,参数保持为 0。
时间限制 3000 ms · 内存限制 256 MB
本平台为独立第三方培训机构,与华为技术有限公司无任何关联;课程的服务内容与权益以购买协议为准,学习效果因个人情况而异。「华为 OD」「华为可信」等仅为对岗位与考试方向的客观描述,相关商标归各自权利人所有。
训练营动画视频讲解
登录后可查看你在本题的历史提交,以及每次的各用例通过情况。
© 2026 广州慕课网络科技有限公司 · 吴师兄学算法官网 版权所有
这些是真正决定能不能 AC、但通用题解里常被略过的点。
先只使用训练集计算每一列的最小值和最大值,并用同一组参数归一化训练样本与查询样本;常量列统一映射为 0。参数从 0 开始,执行 e 轮批量梯度下降:一轮内先基于同一组旧参数计算全部预测和梯度,再同时更新偏置与所有权重。最后用训练得到的参数预测查询样本。
Min-Max 变换严格使用训练集统计量,避免查询数据影响模型参数。MSE 对偏置和权重的梯度分别为 (2/n)Σerror 与 (2/n)Σ(error·x_j);代码逐项累加的正是这两个公式。同步更新保证每轮等价于标准批量梯度下降。
归一化需要 O((n+m)d),训练需要 O(end),预测需要 O(md);保存训练数据需要 O(nd),参数和梯度需要 O(d)。
e=0 时参数保持为零。常量列不能做除零运算;查询值允许落在训练集范围之外,不应额外截断。不要在一轮中更新偏置后再用新偏置计算其他梯度。
# Min-Max 用训练集的列 min/max(常量列归 0),查询同参数换算不截断;
# 批量 GD:MSE 梯度带 2/n 系数,一轮内基于旧参数算完全部梯度再同步更新。
import sys
def solve() -> None:
data = sys.stdin.buffer.read().split()
if not data:
return
it = iter(data)
n, d, m, epochs = (int(next(it)) for _ in range(4))
eta = float(next(it))
x, y = [], []
for _ in range(n):
x.append([float(next(it)) for _ in range(d)])
y.append(float(next(it)))
query = [[float(next(it)) for _ in range(d)] for _ in range(m)]
lo = [min(row[j] for row in x) for j in range(d)]
hi = [max(row[j] for row in x) for j in range(d)]
def norm(row):
return [0.0 if hi[j] == lo[j] else (row[j] - lo[j]) / (hi[j] - lo[j]) for j in range(d)]
train = [norm(row) for row in x]
weights = [0.0] * d
bias = 0.0
for _ in range(epochs):
grad_w = [0.0] * d
grad_b = 0.0
for row, target in zip(train, y):
error = bias + sum(weights[j] * row[j] for j in range(d)) - target
grad_b += error
for j in range(d):
grad_w[j] += error * row[j]
scale = 2.0 / n
bias -= eta * scale * grad_b
for j in range(d):
weights[j] -= eta * scale * grad_w[j]
out = []
for row in query:
row = norm(row)
value = bias + sum(weights[j] * row[j] for j in range(d))
if abs(value) < 0.00005:
value = 0.0
out.append(f"{value:.4f}")
print("\n".join(out))
if __name__ == "__main__":
solve()