题解 | #小美的平衡矩阵#

我的思路是把 1 当作 1,0 当作 -1,1 和 0 的个数相等等价于矩阵中所有元素之和为 0。

对于 k 从 1 到 n,遍历所有矩阵,计算和为 0 的矩阵的个数,就是 k * k 的完美矩阵的个数。

现在的问题是:如何快速计算从 (i, j) 开始,大小为 k * k 的矩阵的元素的和? (将其设为 f(i, j, k))

当前要计算的 k * k 矩阵的元素和 = 左上方的 (k - 1) * (k - 1) 矩阵的元素和 + 最下面一行元素的和 + 最右边一列元素的和 - 右下方的元素(因为重复算了一次)

matrix(i, j) 表示矩阵第 i 行第 j 列的元素,rowPrefix(i, j) 表示第 i 行前 j 个元素的和,colPrefix(i, j) 表示第 i 列前 j 个元素的和,那么由前缀和有:

f(i, j, k) = f(i, j, k - 1) + rowPrefix(i + k - 1, j + k - 1) - rowPrefix(i + k - 1, j - 1) + colPrefix(j + k - 1, i + k - 1) - colPrefix(j + k - 1, i - 1) - matrix(i, j)

根据此公式Js答案如下:

const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;

void async function () {
    // 读取矩阵
    const n = parseInt(await readline())
    const matrix = new Array(n + 1)
    for(let i = 1; i <= n; i++) {
        matrix[i] = new Array(n + 1)
        const nums = (await readline()).split('')
        for(let j = 0; j < nums.length; j++){
            // '1' 存 1,'0' 存 -1,方便算和
            matrix[i][j + 1] = nums[j] === '1' ? 1 : -1
        }
    }

    // 初始化行和列的前缀和
    const rowPrefix = new Array(n + 1)
    const colPrefix = new Array(n + 1)
    for(let i = 1; i <= n; i++) {
        rowPrefix[i] = new Array(n + 1)
        colPrefix[i] = new Array(n + 1)
        rowPrefix[i][0] = 0
        colPrefix[i][0] = 0
        for(let j = 1; j <= n; j++) {
            rowPrefix[i][j] = rowPrefix[i][j - 1] + matrix[i][j]
            colPrefix[i][j] = colPrefix[i][j - 1] + matrix[j][i]
        }
    }

    // 初始化 map 记录前缀和
    let map = new Map()
    for(let i = 1; i <= n; i++) {
        for(let j = 1; j <= n; j++) {
            map.set(`${i} ${j}`, matrix[i][j])
        }
    }
    console.log(0)

    for(let k = 2; k <= n; k++) {
        let newMap = new Map()
        let res, count = 0, row, col
        for(let i = 1; i <= n - k + 1; i++) {
            for(let j = 1; j <= n - k + 1; j++) {
                row = i + k - 1
                col = j + k - 1
                res = map.get(`${i} ${j}`) + rowPrefix[row][col] - rowPrefix[row][j - 1] + colPrefix[col][row] - colPrefix[col][i - 1] - matrix[row][col]
                if(res === 0) {
                    count++    
                }
                newMap.set(`${i} ${j}`, res)
            }
        }
        console.log(count)
        // 更新 map
        map = newMap
    }
}()
全部评论

相关推荐

4 1 评论
分享
牛客网
牛客企业服务