美团校招机试 - 小美的平衡矩阵(20240309-T1)

news2024/11/16 12:49:13

题目来源

美团校招笔试真题_小美的平衡矩阵

题目描述

小美拿到了一个 n * n  的矩阵,其中每个元素是 0 或者 1。

小美认为一个矩形区域是完美的,当且仅当该区域内 0 的数量恰好等于 1 的数量。

现在,小美希望你回答有多少个 i * i 的完美矩形区域。你需要回答 1 ≤ i ≤ n 的所有答案。

输入描述

第一行输入一个正整数 n,代表矩阵大小。

  • 1 ≤ n ≤ 200

接下来的 n 行,每行输入一个长度为 n 的 01 串,用来表示矩阵。

输出描述

输出 n 行,第 i 行输出的 i * i 的完美矩形区域的数量。

用例

输入4
1010
0101
1100
0011
输出0
7
0
1
说明

题目解析

本题需要我们求解 i * i 的完美矩形区域的数量,i 取值 1~n.

完美矩形区域:当且仅当该区域内 0 的数量恰好等于 1 的数量

比如下图中黄色部分是一个 2x2 的矩形区域,其中01数量相等,因此是一个完美矩形区域

因此,本题的关键其实是,求解输入矩阵中,任意 i * i 正方形区域中 '1' 的数量oneCount,如果满足: oneCount * 2 == i * i,则对应正方形区域是完美的。

那么,如何求解输入矩阵中,任意正方形区域中 '1' 的数量呢?

我们可以基于“二维数组前缀和”的知识来求解。

假设 dp[i][j] 表示输入矩阵中以 (0,0)为左上角点,(i,j)为右下角点的矩形中 '1' 的数量。

比如上图中,dp[1][1] = 2,即以(0,0)为左上角点,(1,1)为左下角点的矩形中 '1' 的数量为 2。

下图中红色区域1的数量存在关系如下:

其中橙色区域 是 绿色和蓝色区域的重叠区域,为了避免重复计算,所以要减去。

即存在状态转移方程如下:

dp[i][j] = dp[i][j-1]dp[i-1][j] - dp[i-1][j-1] + (matrix[i][j] == '1' ? 1 : 0)

上面状态转移方程求解i=0, j=0的右下角位置矩形时,会发生越界异常,

因此我们定义dp二维数组时,需要将dp矩阵的行数、列数都定义为n+1。dp矩阵的第一行和第一列初始为0。

之后,我们就可以遍历dp中所有正方形,然后基于dp来求解正方形中1的数量。比如下图中:

我们要求解:边长为 i=2,右下角位置 (r=3, c=2) 的正方形中 '1' 的数量,则有公式如下:

dp[r][c] - dp[r][c - i] - dp[r - i][c] + dp[r - i][c - i]

公式可以对照下图理解: 

JS(Node)算法源码

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 = [];
  for (let i = 0; i < n; i++) {
    matrix.push(await readline());
  }

  // 二维数组前缀和
  // dp[i][j] 表示matrix矩阵中以 (i-1, j-1) 位置为右下角点的矩形中1的数量
  const dp = new Array(n + 1).fill(0).map(() => new Array(n + 1).fill(0));
  for (let i = 1; i <= n; i++) {
    for (let j = 1; j <= n; j++) {
      // 此处公式请看图示说明
      dp[i][j] =
        parseInt(matrix[i - 1][j - 1]) +
        dp[i - 1][j] +
        dp[i][j - 1] -
        dp[i - 1][j - 1];
    }
  }

  // i 表示正方形边长
  for (let i = 2; i <= n; i += 2) {
    // i 为奇数时, 则对应 i*i 正方形面积也为奇数, 不可能平分, 所以不存在01平衡的
    console.log(0);

    // i 为偶数时
    let count = 0; // 记录01平衡的i*i正方形数量
    for (let r = i; r <= n; r++) {
      for (let c = i; c <= n; c++) {
        // 正方形中1的数量
        const oneCount =
          dp[r][c] - dp[r][c - i] - dp[r - i][c] + dp[r - i][c - i];

        // 如果正方形中1的数量 == 正方形面积的一半,则形成01平衡
        if (oneCount * 2 == i * i) {
          count++;
        }
      }
    }
    console.log(count);
  }

  // 如果 n 是奇数,则上面for循环会遗漏 n*n 正方形的01平衡判断
  if (n % 2 != 0) {
    console.log(0);
  }
})();

Java算法源码

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int n = Integer.parseInt(sc.nextLine());

        char[][] matrix = new char[n][n];
        for (int i = 0; i < n; i++) {
            matrix[i] = sc.nextLine().toCharArray();
        }

        // 二维数组前缀和
        // dp[i][j] 表示matrix矩阵中以 (i-1, j-1) 位置为右下角点的矩形中1的数量
        int[][] dp = new int[n + 1][n + 1];
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                // 此处公式请看图示说明
                dp[i][j] = (matrix[i - 1][j - 1] - '0') + dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1];
            }
        }

        // i 表示正方形边长
        for (int i = 2; i <= n; i += 2) {
            // i 为奇数时, 则对应 i*i 正方形面积也为奇数, 不可能平分, 所以不存在01平衡的
            System.out.println(0);

            // i 为偶数时
            int count = 0; // 记录01平衡的i*i正方形数量
            for (int r = i; r <= n; r++) {
                for (int c = i; c <= n; c++) {
                    // 正方形中1的数量
                    int oneCount = dp[r][c] - dp[r][c - i] - dp[r - i][c] + dp[r - i][c - i];

                    // 如果正方形中1的数量 == 正方形面积的一半,则形成01平衡
                    if (oneCount * 2 == i * i) {
                        count++;
                    }
                }
            }
            System.out.println(count);
        }

        // 如果 n 是奇数,则上面for循环会遗漏 n*n 正方形的01平衡判断
        if (n % 2 != 0) {
            System.out.println(0);
        }
    }
}

Python算法源码

# 输入获取
n = int(input())
matrix = [input() for _ in range(n)]

# 核心代码
if __name__ == '__main__':
    # 二维数组前缀和
    # dp[i][j] 表示matrix矩阵中以 (i-1, j-1) 位置为右下角点的矩形中1的数量
    dp = [[0] * (n + 1) for _ in range(n + 1)]

    for i in range(1, n + 1):
        for j in range(1, n + 1):
            # 此处公式请看图示说明
            dp[i][j] = int(matrix[i - 1][j - 1]) + dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1]

    # i 表示正方形边长
    for i in range(2, n + 1, 2):
        # i 为奇数时, 则对应 i*i 正方形面积也为奇数, 不可能平分, 所以不存在01平衡的
        print(0)

        # i 为偶数时
        count = 0  # 记录01平衡的i*i正方形数量
        for r in range(i, n + 1):
            for c in range(i, n + 1):
                # 正方形中1的数量
                oneCount = dp[r][c] - dp[r][c - i] - dp[r - i][c] + dp[r - i][c - i]

                # 如果正方形中1的数量 == 正方形面积的一半,则形成01平衡
                if oneCount * 2 == i * i:
                    count += 1

        print(count)

    # 如果 n 是奇数,则上面for循环会遗漏 n*n 正方形的01平衡判断
    if n % 2 != 0:
        print(0)

C算法源码

#include <stdio.h>

#define MAX_SIZE 201

int main() {
    int n;
    scanf("%d", &n);

    char matrix[MAX_SIZE][MAX_SIZE] = {'\0'};
    for (int i = 0; i < n; i++) {
        scanf("%s", matrix[i]);
    }

    // 二维数组前缀和
    // dp[i][j] 表示matrix矩阵中以 (i-1, j-1) 位置为右下角点的矩形中1的数量
    int dp[MAX_SIZE][MAX_SIZE] = {0};
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            // 此处公式请看图示说明
            dp[i][j] = (matrix[i - 1][j - 1] - '0') + dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1];
        }
    }

    // i 表示正方形边长
    for (int i = 2; i <= n; i += 2) {
        // i 为奇数时, 则对应 i*i 正方形面积也为奇数, 不可能平分, 所以不存在01平衡的
        puts("0");

        // i 为偶数时
        int count = 0; // 记录01平衡的i*i正方形数量
        for (int r = i; r <= n; r++) {
            for (int c = i; c <= n; c++) {
                // 正方形中1的数量
                int oneCount = dp[r][c] - dp[r][c - i] - dp[r - i][c] + dp[r - i][c - i];

                // 如果正方形中1的数量 == 正方形面积的一半,则形成01平衡
                if (oneCount * 2 == i * i) {
                    count++;
                }
            }
        }
        printf("%d\n", count);
    }

    // 如果 n 是奇数,则上面for循环会遗漏 n*n 正方形的01平衡判断
    if (n % 2 != 0) {
        puts("0");
    }

    return 0;
}

C++算法源码

#include <bits/stdc++.h>
using namespace std;

int main() {
    int n;
    cin >> n;

    vector<string> matrix(n);
    for (int i = 0; i < n; i++) {
        cin >> matrix[i];
    }

    // 二维数组前缀和
    // dp[i][j] 表示matrix矩阵中以 (i-1, j-1) 位置为右下角点的矩形中1的数量
    vector<vector<int>> dp(n + 1, vector<int>(n + 1, 0));
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            // 此处公式请看图示说明
            dp[i][j] = (matrix[i - 1][j - 1] - '0') + dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1];
        }
    }

    // i 表示正方形边长
    for (int i = 2; i <= n; i += 2) {
        // i 为奇数时, 则对应 i*i 正方形面积也为奇数, 不可能平分, 所以不存在01平衡的
        cout << 0 << endl;

        // i 为偶数时
        int count = 0; // 记录01平衡的i*i正方形数量
        for (int r = i; r <= n; r++) {
            for (int c = i; c <= n; c++) {
                // 正方形中1的数量
                int oneCount = dp[r][c] - dp[r][c - i] - dp[r - i][c] + dp[r - i][c - i];

                // 如果正方形中1的数量 == 正方形面积的一半,则形成01平衡
                if (oneCount * 2 == i * i) {
                    count++;
                }
            }
        }

        cout << count << endl;
    }

    // 如果 n 是奇数,则上面for循环会遗漏 n*n 正方形的01平衡判断
    if (n % 2 != 0) {
        cout << 0 << endl;
    }

    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1869465.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

软件测试面试题:Web View如何测试?

Web View介绍 Web View&#xff08;网页视图&#xff09;是一种用于在应用程序中显示网页内容的组件或控件。提供了一种将网页内容嵌入到应用程序中的方式&#xff0c;使用户能够在应用程序中浏览和交互网页。 Web View通常用于开发移动应用程序&#xff0c;特别是混合应用程…

SOBEL图像边缘检测器的设计

本项目使用FPGA设计出SOBEL图像边缘检测器&#xff0c;通过分析项目在使用过程中的工作原理和相关软硬件设计进行分析详细介绍SOBEL图像边缘检测器的设计。 资料获取可联系wechat 号&#xff1a;comprehensivable 边缘可定义为图像中灰度发生急剧变化的区域边界,它是图像最基本…

2024年G1工业锅炉司炉证考试题库及G1工业锅炉司炉试题解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年G1工业锅炉司炉证考试题库及G1工业锅炉司炉试题解析是安全生产模拟考试一点通结合&#xff08;安监局&#xff09;特种作业人员操作证考试大纲和&#xff08;质检局&#xff09;特种设备作业人员上岗证考试大纲…

LED裸眼3D显示屏:开启视觉新体验

随着科技的不断进步&#xff0c;LED显示屏作为一种新型的显示技术&#xff0c;已经被广泛应用于各个领域。而其中&#xff0c;LED裸眼3D显示屏更是因其独特的技术原理和令人震撼的视觉效果&#xff0c;成为了业界关注的焦点。 裸眼3D显示屏是一种前沿的显示技术&#xff0c;它…

超越规模的冒险之旅:引导人工智能价值对齐

在茫茫技术之林中&#xff0c;人工智能凭借大模型占据了重要地位。人们已经不再局限于人机对弈和AI识图&#xff0c;开始探索那些能够模仿人类思考的机器。无论是日常聊天、文本写作&#xff0c;还是[在完美的提示词引导下创作出惊艳的诗歌]&#xff0c;我们不得不承认AI工具已…

计算机网络:如何隐藏真实的IP和MAC地址?

目录 一、什么是MAC地址二、什么是IP地址三、如何隐藏真实的MAC地址四、如何隐藏真实的IP地址 一、什么是MAC地址 MAC地址&#xff0c;全称为媒体访问控制地址&#xff08;Media Access Control Address&#xff09;&#xff0c;是一种用于网络通信的唯一标识符。它是由IEEE 8…

Windows 计划任务 运行 Bat 的配置参考

打开Windows 计划任务- 创建任务 属性设置 - 常规 属性设置 - 触发器 属性设置 - 操作

今天不看文章,明天变垃圾(明天收费)-----字节数据分析发展过程中所遭遇的挑战

字节数据分析发展过程中所遭遇的挑战 三个核心议题&#xff1a; 海量数据分析性能&#xff1a;会议指出Spark分析性能不足成为了一个显著问题&#xff0c;尤其是在需要毫秒级响应的业务场景中。实时导入与查询能力&#xff1a;目前Kylin只能以T1的形式提供分析服务&#xff0…

MySQL内存使用率高且不释放问题排查与总结

背景 生产环境mysql 5.7内存占用超过90%以上&#xff0c;且一直下不来。截图如下&#xff1a; 原因分析 1、确定mysql具体的占用内存大小&#xff0c;通过命令&#xff1a;cat /proc/Mysql进程ID/status查看 命令执行后的结果比较多&#xff08;其他参数的含义想了解可参考这…

Redis-实战篇-实现商铺缓存与数据库的双写一致(超时剔除和主动更新)

文章目录 1、给查询商铺的缓存添加超时剔除和主动更新的策略2、根据id查询店铺2.1、queryById2.2、RedisConstants.java 3、根据id修改店铺3.1、ShopController.java3.2、update 1、给查询商铺的缓存添加超时剔除和主动更新的策略 修改ShopController中的业务逻辑&#xff0c;满…

ONLYOFFICE 桌面编辑器 8.1华丽登场

简介&#xff1a;全新ONLYOFFICE 桌面编辑器 8.1解锁全新PDF编辑、幻灯片优化与本地化体验&#xff0c;立即下载&#xff01; 前言&#xff1a;在数字化时代&#xff0c;高效的办公协作工具是企业和个人不可或缺的利器。ONLYOFFICE&#xff0c;作为一款功能强大的云端和桌面办公…

亚马逊风控策略揭秘:测评系统为何这么重要?

在亚马逊这个竞争激烈的电商平台上&#xff0c;许多卖家都渴望通过测评来提升产品销量和排名。然而&#xff0c;亚马逊对测评行为的监管之严格&#xff0c;可以说是业内首屈一指。即便你采用的是由真实客户购买并评价的“真人测评”模式&#xff0c;也难免存在一定的风险。 那么…

Psychtoolbox 脑电实验范式之mp4视频绘制

1. 读取 首先需要使用到Screen(‘OpenMovie’)函数&#xff0c;该函数可以读取mp4、gif格式的数据&#xff0c;具体方式如下&#xff1a; clear; clc; Screen(Preference, SkipSyncTests, 1); screens Screen(Screens); screenNum max(screens); [window, screenRect] Scr…

参加六西格玛绿带培训是投资未来,还是花冤枉钱?

是否值得花费资金参加六西格玛绿带培训&#xff0c;取决于多个因素。 从积极的方面来看&#xff0c;参加六西格玛绿带培训具有以下潜在价值&#xff1a; 1. 提升专业技能&#xff1a;使您掌握一套系统的问题解决方法和流程改进工具&#xff0c;有助于在工作中更高效地解决复杂…

甄美天使1+3退休模式创富模型,甄美天使商业模式特点

甄美天使13退休模式级差&#xff0c;每个人都有机会成为千万的受益人&#xff1b; 坐标&#xff1a;厦门&#xff0c;我是肖琳 深耕社交新零售行业10年&#xff0c;主要提供新零售系统工具及顶层商业模式设计、全案策划运营陪跑等。 甄美天使的创富模型采用了社交电商的传播理…

千年织锦:中国古代包文化的辉煌历程与现代传承

追溯至远古&#xff0c;我们的祖先就开始利用自然界的恩赐——皮革、植物纤维等&#xff0c;制作出最原始的包袋。随着时间的推移&#xff0c;技艺的提升&#xff0c;包的材质逐渐丰富起来&#xff0c;从粗糙到精致&#xff0c;从简单到复杂&#xff0c;每一次材质的革新都是人…

Linux学习第54天:Linux WIFI 驱动:蓝星互联

Linux版本号4.1.15 芯片I.MX6ULL 大叔学Linux 品人间百味 思文短情长 数字化、现代化的今天&#xff0c;随处的WIFI给与了大众极大的方便&#xff0c;也感受到了科技的力量。万物互联、无线互联越来越成为一个不可逆转的趋势。现在比较火…

面试相关-接口测试常问的问题

1.为什么要做接口测试 (1)现在大多系统都是前后端分离的项目,前端和后端的进度可能不一样,那为了尽早的进入测试,前端界面没有开发完成的情况下,只要后端的接口开发完了,就可以提前做接口测试了; (2)基于安全考虑,只依赖前端进行限制,已经完全不满足系统的安全性…

DLS MARKETS外汇:日元暴跌,日本是否会再次干预汇市?

摘要 近日&#xff0c;日元兑美元汇率暴跌至1986年以来的最低水平&#xff0c;引发市场对日本政府可能再次干预汇市的猜测。尽管地缘政治紧张局势为日元带来压力&#xff0c;但美国和日本之间的巨大利差也是关键因素。本文将详细分析当前日元贬值的原因、日本当局的可能反应以及…

Java 自定义jackson2序列化器遇到的问题

问题1&#xff1a;java: 错误: 不支持发行版本 5 修改idea java环境 问题2&#xff1a;ClassNotFoundException: com.fasterxml.jackson.annotation.JsonMerge 缺少 jar 包&#xff1a;jackson-annotations 引入依赖的地址&#xff1a;https://mvnrepository.com/artifact/c…