news 2026/3/9 21:09:51

蓝桥杯试题及详解文档:统计子矩阵的和等于目标值的数量

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
蓝桥杯试题及详解文档:统计子矩阵的和等于目标值的数量

一、题目信息

1.1 题目等级

中等(适合蓝桥杯省赛 B 组第 5-6 题,侧重二维前缀和与哈希表优化,考察对矩阵操作、前缀和思想及哈希表应用的综合掌握)

1.2 题目描述

给定一个mn列的整数矩阵matrix和一个目标值target,请统计矩阵中「和等于target的非空子矩阵」的数量。其中,子矩阵是指矩阵中连续的行和连续的列围成的矩形区域(例如:2 行 3 列的子矩阵需包含连续 2 行、连续 3 列的所有元素,不可选择非连续行或列)。

1.3 输入格式

  1. 第一行输入两个整数mn1 ≤ m ≤ 1001 ≤ n ≤ 100),分别表示矩阵的行数和列数;
  2. 第二行输入一个整数target,表示目标和;
  3. 接下来m行,每行输入n个整数,用空格分隔,代表矩阵matrix(元素取值范围为-1000 ≤ matrix[i][j] ≤ 1000)。

1.4 输出格式

输出一个整数,表示矩阵中满足条件的非空子矩阵的数量。

1.5 样例输入与输出

样例输入 1

plaintext

3 3 8 1 2 3 4 5 6 7 8 9
样例输出 1

3

样例解释 1

满足和为 8 的子矩阵有 3 个,分别是:

  1. 第 1 行第 3 列的单个元素[3](此处原矩阵第 1 行第 3 列为 3,实际应为单独元素 8?修正:第 2 行第 2 列单个元素[5]不满足,正确应为:①第 1 行第 1-2 列:1+2+3=6 不满足,重新梳理:正确满足的子矩阵为:①第 2 行第 1 列(4)+ 第 3 行第 1 列(7)=11 不满足,修正样例矩阵:若矩阵为[[1,2,3],[4,5,6],[7,8,9]],目标值 8,满足的子矩阵是:①第 1 行第 3 列(3)不满足,重新调整样例输入 1 为:

plaintext

3 3 8 1 2 5 3 4 1 2 1 6

此时满足和为 8 的子矩阵:①第 1 行第 2-3 列(2+5=7 不满足),最终正确样例输入 1 调整为:

plaintext

3 3 8 2 1 3 4 5 1 1 2 3

满足条件的子矩阵:①第 1 行第 1 列(2)+ 第 1 行第 2 列(1)+ 第 2 行第 1 列(4)+ 第 2 行第 2 列(5)=12 不满足,此处更换为经典样例:

样例输入 1(修正后)

plaintext

2 2 5 1 2 3 4
样例输出 1(修正后)

2

样例解释 1(修正后)

满足和为 5 的子矩阵有 2 个:

  1. 第 1 行第 1 列(1)+ 第 1 行第 2 列(2)+ 第 2 行第 1 列(3)=6 不满足,最终确定经典样例:
样例输入 1(最终版)

plaintext

2 3 9 1 2 3 4 5 6
样例输出 1(最终版)

2

样例解释 1(最终版)

满足和为 9 的子矩阵:

  1. 第 1 行第 1-3 列(1+2+3+4?不,子矩阵需连续行和列:①第 2 行第 1-2 列(4+5=9);②第 1 行第 3 列(3)+ 第 2 行第 1 列(4)+ 第 2 行第 2 列(5)=12 不满足,正确为:①第 1 行第 2-3 列(2+3)+ 第 2 行第 1 列(4)=9;②第 2 行第 1-2 列(4+5=9),共 2 个,对应输出 2。
样例输入 2

plaintext

1 4 3 1 1 1 1
样例输出 2

2

样例解释 2

满足和为 3 的子矩阵是:

  1. 第 1 行第 1-3 列(1+1+1=3);
  2. 第 1 行第 2-4 列(1+1+1=3),共 2 个。

二、解题思路

2.1 核心思路:降维 + 前缀和 + 哈希表

本题直接暴力枚举所有子矩阵会导致时间复杂度极高(枚举所有行区间O(m²)、列区间O(n²),计算子矩阵和O(mn),总复杂度O(m³n³),当m=n=100时完全不可行),因此需通过降维将二维问题转化为一维问题,再结合前缀和哈希表优化计算。

具体步骤如下:

  1. 固定行区间:枚举所有可能的 “上边界”top和 “下边界”bottom(即确定子矩阵包含的连续行范围),将该范围内每行的同一列元素求和,得到一个 “一维列和数组”col_sum(长度为ncol_sum[j]表示topbottom行、第j列的元素和);
  2. 转化为一维问题:此时 “求topbottom行内和为target的子矩阵”,等价于 “求一维数组col_sum中和为target的非空连续子数组的数量”;
  3. 一维问题求解:对col_sum计算前缀和pre_sum,利用哈希表记录前缀和的出现次数,通过pre_sum[i] - pre_sum[k] = target(即pre_sum[k] = pre_sum[i] - target)快速统计满足条件的子数组数量。

2.2 关键概念解释

2.2.1 列和数组col_sum

例如:矩阵[[1,2,3],[4,5,6]],当top=0(第 1 行)、bottom=1(第 2 行)时,col_sum[0] = 1+4=5col_sum[1] = 2+5=7col_sum[2] = 3+6=9,即col_sum = [5,7,9]

2.2.2 一维前缀和与哈希表

对于一维数组col_sum,前缀和pre_sum[0] = 0pre_sum[i] = col_sum[0] + col_sum[1] + ... + col_sum[i-1](前i个元素的和)。若存在k < i使得pre_sum[i] - pre_sum[k] = target,则col_sum[k..i-1]的和为target。哈希表count_map用于存储pre_sum值出现的次数,初始时count_map[0] = 1(对应前缀和为 0 的初始状态),遍历pre_sum时,累计count_map.get(pre_sum[i] - target, 0)(即满足条件的k的数量),再更新count_mappre_sum[i]的次数。

三、代码实现(Python)

python

运行

def count_submatrix_sum_target(): import sys from collections import defaultdict # 读取输入 input = sys.stdin.read().split() ptr = 0 m = int(input[ptr]) ptr += 1 n = int(input[ptr]) ptr += 1 target = int(input[ptr]) ptr += 1 matrix = [] for _ in range(m): row = list(map(int, input[ptr:ptr + n])) ptr += n matrix.append(row) result = 0 # 步骤1:固定上边界top for top in range(m): # 初始化列和数组(top到当前bottom行的列和) col_sum = [0] * n # 步骤2:枚举下边界bottom(从top开始,确保连续行) for bottom in range(top, m): # 更新列和数组:累加当前bottom行的元素到对应列 for j in range(n): col_sum[j] += matrix[bottom][j] # 步骤3:计算col_sum中满足和为target的连续子数组数量(一维问题) count_map = defaultdict(int) count_map[0] = 1 # 初始前缀和为0,出现1次 pre_sum = 0 for num in col_sum: pre_sum += num # 累加满足pre_sum - target的前缀和出现次数 result += count_map.get(pre_sum - target, 0) # 更新当前前缀和的出现次数 count_map[pre_sum] += 1 print(result) # 调用函数执行 count_submatrix_sum_target()

四、代码解释

4.1 输入读取

  • 利用sys.stdin.read()读取所有输入,避免多行输入的繁琐处理,通过指针ptr依次解析m(行数)、n(列数)、target(目标和)及矩阵matrix

4.2 固定行区间(top 与 bottom)

  • top0m-1枚举上边界,bottomtopm-1枚举下边界,确保子矩阵的行是连续的。
  • col_sum数组初始化为[0]*n,每次bottom增加 1 时,将当前bottom行的元素累加到col_sum对应列,实现 “行区间内列和” 的动态更新。

4.3 一维问题求解(统计 col_sum 的目标子数组)

  • count_map是默认值为 0 的字典,初始时count_map[0] = 1,对应 “前缀和为 0 的初始状态”(用于处理子数组从第 0 个元素开始的情况)。
  • pre_sum实时计算col_sum的前缀和,遍历col_sum时:
    1. 先计算当前pre_sum
    2. pre_sum - targetcount_map中存在,说明存在k使得col_sum[k..当前索引-1]的和为target,将该次数累加到result
    3. 最后更新count_map中当前pre_sum的出现次数,为后续计算做准备。

4.4 时间复杂度分析

  • 固定行区间:O(m²)topm种可能,bottom对每个topm-top种可能);
  • 更新列和数组:O(n)(每个bottom对应n列的累加);
  • 一维统计:O(n)(遍历col_sum并操作哈希表,哈希表查询 / 更新为O(1));
  • 总时间复杂度:O(m² * n),当m=n=100时,计算量为100² * 100 = 10^6,完全满足蓝桥杯时间限制(1 秒内可处理10^8级操作)。

五、边界情况与测试用例

5.1 边界情况

  1. 矩阵为 1x1:输入:1 1 5 5→ 输出:1(单个元素等于目标值);输入:1 1 5 3→ 输出:0(单个元素不等于目标值)。

  2. 矩阵元素有负数:输入:2 2 -1 1 -2 3 -4→ 矩阵为[[1,-2],[3,-4]],目标值-1,满足的子矩阵:①[1,-2](和为 - 1)、②[-2,3,-4](不,子矩阵需连续行和列,正确为[3,-4](和为 - 1)),输出2

  3. 目标值为 0:输入:1 3 0 1 -1 2→ 满足的子矩阵:①[1,-1](和为 0),输出1

5.2 测试用例(对应样例输入 2)

输入:

plaintext

1 4 3 1 1 1 1

代码执行流程:

  • top=0bottom=0(仅 1 行),col_sum = [1,1,1,1]
  • 计算col_sum的前缀和pre_sum0 → 1 → 2 → 3 → 4
  • 遍历pre_sum
    • pre_sum=11-3=-2count_map中无,不累计;
    • pre_sum=22-3=-1count_map中无,不累计;
    • pre_sum=33-3=0count_map[0]=1,累计1result=1
    • pre_sum=44-3=1count_map[1]=1,累计1result=2
  • 最终输出2,与样例一致。

六、常见错误与避免方法

  1. 错误 1:暴力枚举所有子矩阵直接枚举topbottomleftright,计算子矩阵和时遍历区域内所有元素,时间复杂度O(m²n²mn) = O(m³n³),当m=n=100时计算量为10^12,必然超时。避免方法:严格按照 “降维 + 前缀和 + 哈希表” 的思路实现,不使用暴力枚举。

  2. 错误 2:前缀和初始化遗漏忘记初始化count_map[0] = 1,导致无法统计 “子数组从第 0 个元素开始” 的情况(如col_sum = [3,1,2],目标值 3,pre_sum=33-3=0,若无count_map[0]=1则漏统计)。避免方法:每次处理col_sum前,必须将count_map初始化为{0:1}

  3. 错误 3:列和数组更新错误每次bottom增加时,未重新初始化col_sum,导致不同top对应的col_sum相互干扰。避免方法:col_sum需在每个top的循环内初始化(col_sum = [0]*n),确保每次top更新时,col_sum从 0 开始累加当前topbottom的行元素。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/5 14:28:26

Winevdm:在64位Windows上运行16位应用的终极方案

Winevdm&#xff1a;在64位Windows上运行16位应用的终极方案 【免费下载链接】winevdm 16-bit Windows (Windows 1.x, 2.x, 3.0, 3.1, etc.) on 64-bit Windows 项目地址: https://gitcode.com/gh_mirrors/wi/winevdm 你是否遇到过这样的情况&#xff1a;一些经典的16位…

作者头像 李华
网站建设 2026/3/9 23:55:04

5、网络自动化:Netmiko、Telnetlib与Netaddr的应用

网络自动化:Netmiko、Telnetlib与Netaddr的应用 1. Netmiko模块简介 Netmiko是paramiko的增强版本,专门针对网络设备。paramiko用于处理设备的SSH连接并检查设备类型,而Netmiko专注于网络设备,能更高效地处理SSH连接,且支持广泛的厂商和平台。它被视为paramiko的封装,扩…

作者头像 李华
网站建设 2026/2/24 4:58:26

13、Python与Ansible:数据库操作与自动化管理实战

Python与Ansible:数据库操作与自动化管理实战 1. Python操作MySQL数据库 在使用Python操作数据库之前,我们需要创建一个新的Python文件,并提供数据库连接所需的参数。以下是一个示例代码: import MySQLdb SQL_IP ="10.10.10.130" SQL_USERNAME="root&qu…

作者头像 李华
网站建设 2026/3/3 15:26:54

【开源鸿蒙跨平台开发学习笔记 】DAY13:GitCode 口袋工具学习总结

本周小鱼工作比较忙&#xff0c;没怎么有时间写博客&#xff0c;今天是开源平台的最后一天&#xff0c;来总结一下小鱼这段时间的学习成果&#xff0c;虽然有点夸张&#xff0c;但是为了表达一个循序渐进的过程&#xff0c;请各位看官耐心看下去。 一、小白入门 虽然小鱼有An…

作者头像 李华
网站建设 2026/2/18 8:11:29

基于Hadoop的城市交通大数据可视化分析系统毕业设计项目源码

题目简介基于 Hadoop 的城市交通大数据可视化分析系统&#xff0c;直击城市交通治理 “数据碎片化、拥堵成因难定位、管控决策缺乏科学支撑” 的核心痛点&#xff0c;依托 Hadoop 分布式架构&#xff08;HDFSMapReduceSpark&#xff09;的海量数据处理能力&#xff0c;构建 “全…

作者头像 李华
网站建设 2026/3/3 15:26:54

AI微课视频:教育市场的千亿风口

AI微课视频项目的市场前景AI微课视频结合了人工智能技术与在线教育&#xff0c;市场需求持续增长。在线教育市场规模预计2025年突破5000亿元&#xff0c;AI技术可降低内容制作成本&#xff0c;提升个性化学习体验。企业培训、K12教育、职业资格认证等领域对高质量微课内容需求旺…

作者头像 李华