news 2026/2/10 8:12:09

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

作者头像

张小明

前端开发工程师

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/2/9 16:55:36

n8n实战营Day3课时3:库存物流联动·全流程测试与异常调试

我将承接上节课订单同步内容&#xff0c;聚焦库存扣减与物流联动的核心实现&#xff0c;重点拆解并发控制与物流API调用技巧&#xff0c;搭配全流程测试方案&#xff0c;结构图采用CSDN适配的mermaid语法确保清晰呈现。 n8n实战营Day3课时3&#xff1a;库存物流联动全流程测试与…

作者头像 李华
网站建设 2026/2/5 19:15:48

基于java的SpringBoot/SSM+Vue+uniapp的车联网通信平台的详细设计和实现(源码+lw+部署文档+讲解等)

文章目录前言详细视频演示具体实现截图技术栈后端框架SpringBoot前端框架Vue持久层框架MyBaitsPlus系统测试系统测试目的系统功能测试系统测试结论为什么选择我代码参考数据库参考源码获取前言 &#x1f31e;博主介绍&#xff1a;✌全网粉丝15W,CSDN特邀作者、211毕业、高级全…

作者头像 李华
网站建设 2026/2/7 12:14:12

SAAS-错误处理方法总结

在SAAS的数据源视图中&#xff08;注意这儿的强调词&#xff09;通过外键关联的字段&#xff0c;必须要么为空&#xff0c;要么在主键表中有对应值。不能为0&#xff0c;否则报0值找不到对应键。

作者头像 李华
网站建设 2026/1/30 1:36:24

FTP使用指南:原理、用途及实战操作全解析

文章目录前言网工高频的FTP操作一、版本补丁更新二、配置文件获取三、诊断日志获取介绍FTP一、什么是 FTP&#xff1f;二、FTP vs SFTPFTP软件3CDaemon&#xff08;FTP服务器端&#xff09;Python代码&#xff08;FTP服务器端&#xff09;CMD&#xff08;FTP客户端&#xff09;…

作者头像 李华
网站建设 2026/2/8 4:03:44

Wan2.2-T2V-A14B生成视频是否可通过广电审核标准?

Wan2.2-T2V-A14B生成视频是否可通过广电审核标准&#xff1f; 在AI视频生成技术突飞猛进的今天&#xff0c;一个现实而关键的问题摆在了内容创作者和平台面前&#xff1a;我们用大模型“一键生成”的视频&#xff0c;真的能上电视吗&#xff1f; 别笑&#xff0c;这可不是开玩笑…

作者头像 李华