[R48C]工厂生产


对于 100%100\% 的数据,1n1001 \le n \le 1001ai,j,bj,l1001 \le a_{i, j}, b_{j, l} \le 100

思路

把产品对零件的消耗表 aa 与零件对原料的消耗表 bb 都看作 n×nn \times n 矩阵。生产 11 个「产品 ii」需要的「原料 ll」总数,等于把所有零件 jj 的消耗量乘上该零件对原料 ll 的消耗量后求和:

ci,l=j=1nai,jbj,lc_{i, l} = \sum_{j=1}^{n} a_{i, j} \cdot b_{j, l}

这正是矩阵乘法 c=a×bc = a \times b,直接套用三重循环计算即可。

复杂度

  • 时间:O(n3)O(n^3)n100n \le 100 时约为 10610^6 次运算。
  • 空间:O(n2)O(n^2),存储三个 n×nn \times n 矩阵。
  • 数值:单个 ci,lc_{i, l} 最大为 n×100×100=106n \times 100 \times 100 = 10^6Int64 完全安全。

仓颉实现

import std.env.*
import std.convert.*

main(): Int64 {
    let reader = getStdIn()
    let n = Int64.parse(reader.readln().getOrThrow())
    let nn = n
    // 读入矩阵 a:n 行,每行 n 个整数
    var a = Array<Array<Int64>>(nn, { _ =>
        reader.readln().getOrThrow().split(" ", removeEmpty: true).map({ p: String => Int64.parse(p) })
    })
    // 读入矩阵 b:n 行,每行 n 个整数
    var b = Array<Array<Int64>>(nn, { _ =>
        reader.readln().getOrThrow().split(" ", removeEmpty: true).map({ p: String => Int64.parse(p) })
    })
    // 矩阵乘法 c = a * b
    var sb = StringBuilder()
    for (i in 0..nn) {
        for (l in 0..nn) {
            var sum: Int64 = 0
            for (j in 0..nn) {
                sum += a[i][j] * b[j][l]
            }
            sb.append(sum.toString())
            if (l + 1 < nn) {
                sb.append(" ")
            }
        }
        sb.append("\n")
    }
    print(sb.toString())
    return 0
}