通过率 0% · 提交 0 · 通过 0
这道 OJ 的配套动画
RNN 前向传播 · 对应本题的思路、过程和代码
实现单层循环神经网络(RNN)的前向传播:h_t = tanh(W_x·x_t + W_h·h_{t−1} + b)。h_0 由输入给出,t 从 1 到 T 正向推进,输出每一步的隐藏态。
这类题属于算法机考高频题型中「循环网络 / 前向传播」方向的高频题型,通常考察对「循环网络 / 前向传播」的建模能力与边界条件处理。掌握本题的解题思路后,可举一反三应对同类真题方向,稳步提升机考通过率。
第一行三个整数 T dIn dH。随后 dH 行、每行 dIn 个实数为 W_x;dH 行、每行 dH 个实数为 W_h;1 行 dH 个实数为 b;1 行 dH 个实数为 h_0;随后 T 行、每行 dIn 个实数为 x_1…x_T(均最多两位小数)。
T 行、每行 dH 个数,为 h_1…h_T(四舍五入保留两位小数,单个空格分隔);-0.00 输出 0.00。舍入规则:用语言的标准两位小数格式化(f"{x:.2f}"、printf("%.2f")、String.format("%.2f"))即可;测试数据保证每个待输出值的精确值到 0.005 舍入边界的距离不小于 1e-8,三种语言结果一致,无需自行实现舍入。
1 <= T <= 50;1 <= dIn, dH <= 16;|权重、偏置、h_0| <= 2;|x| <= 4。
示例 1
输入示例
2 2 2 0.50 0.00 0.00 0.50 0.10 0.00 0.00 0.10 0.00 0.00 0.00 0.00 1.00 1.00 1.00 -1.00
输出示例
0.46 0.46 0.50 -0.43
两步,对角权重
时间限制 4000 ms · 内存限制 256 MB
本平台为独立第三方培训机构,与华为技术有限公司无任何关联;课程的服务内容与权益以购买协议为准,学习效果因个人情况而异。「华为 OD」「华为可信」等仅为对岗位与考试方向的客观描述,相关商标归各自权利人所有。
训练营动画视频讲解
登录后可查看你在本题的历史提交,以及每次的各用例通过情况。
从 h_0 开始按时间步计算 z_t=W_xx_t+W_hh_{t-1}+b,再逐维取 tanh 得到 h_t。本步结果写入新数组,整步完成后再替换旧状态。
对时间步归纳:初始状态 h_0 已知;若进入第 t 步时保存的是正确 h_{t-1},公式逐项计算出唯一的 h_t,且同步更新不会污染尚未使用的旧分量。因此所有时间步输出都正确。
时间复杂度 O(T·dH·(dIn+dH)),状态与矩阵之外的额外空间为 O(dH)。
权重全零时每步应为 tanh(b);重点检查只输出格式化后的负零以及矩阵行列方向。
import math
import sys
def fmt(v: float) -> str:
s = f"{v:.2f}"
return "0.00" if s == "-0.00" else s
def main() -> None:
data = sys.stdin.read().split()
it = iter(data)
T = int(next(it)); d_in = int(next(it)); d_h = int(next(it))
read = lambda r, c: [[float(next(it)) for _ in range(c)] for _ in range(r)]
wx = read(d_h, d_in)
wh = read(d_h, d_h)
b = [float(next(it)) for _ in range(d_h)]
h = [float(next(it)) for _ in range(d_h)]
lines = []
for _ in range(T):
x = [float(next(it)) for _ in range(d_in)]
nh = []
for r in range(d_h):
z = b[r]
z += sum(wx[r][c] * x[c] for c in range(d_in))
z += sum(wh[r][c] * h[c] for c in range(d_h)) # 用上一步 h
nh.append(math.tanh(z))
h = nh
lines.append(" ".join(fmt(v) for v in h))
sys.stdout.write("\n".join(lines) + "\n")
if __name__ == "__main__":
main()