当前位置: 首页 > news >正文

【C语言】二维前缀和/求子矩阵之和

相信你是最棒哒!!!

目录

一、题目描述

        正确代码

二、题目描述

题目代码

总结


一、题目描述

输入一个 𝑛 行 𝑚 列的整数矩阵,再输入 𝑞个询问,每个询问包含四个整数 𝑥1,𝑦1,𝑥2,𝑦2,表示一个子矩阵的左上角坐标和右下角坐标。

对于每个询问输出子矩阵中所有数的和。

输入格式

第一行包含三个整数 𝑛,𝑚,𝑞

接下来 𝑛 行,每行包含 𝑚 个整数,表示整数矩阵。

接下来 𝑞 行,每行包含四个整数 𝑥1,𝑦1,𝑥2,𝑦2,表示一组询问。

输出格式

共 𝑞 行,每行输出一个询问的结果。

输入输出样例

输入 

3 4 3
1 7 2 4
3 6 2 8
2 1 2 3
1 1 2 2
2 1 3 4
1 3 3 4

输出 

17
27
21

说明/提示

【数据范围】

1≤𝑛,𝑚≤5000; 1≤𝑞≤100000, 1≤𝑥1≤𝑥2≤𝑛,1≤𝑦1≤𝑦2≤𝑚,

−10000≤矩阵内元素的值≤10000。


正确代码

注释版

#include<stdio.h> long long a[5010][5010], s[5010][5010]; // 定义两个全局二维数组,a用于存储原始数据,s用于存储前缀和int main() /
{long long int n, m, q; // 定义三个长整型变量,分别用于存储矩阵的行数、列数和查询次数scanf("%lld%lld%lld", &n, &m, &q); // 读取矩阵a的值for (int i = 1; i <= n; i++)for (int j = 1; j <= m; j++)scanf("%lld", &a[i][j]);// 计算前缀和矩阵sfor (int i = 1; i <= n; i++)for (int j = 1; j <= m; j++)s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j]; // 根据前缀和的定义计算s[i][j]while (q--) // 进行q次查询{long long int x1, x2, y1, y2; // 定义四个长整型变量,分别用于存储查询的子矩阵的左上角和右下角坐标scanf("%lld%lld%lld%lld", &x1, &y1, &x2, &y2); // 从标准输入读取子矩阵的坐标// 利用前缀和矩阵s计算子矩阵的和long long int sum = s[x2][y2] - s[x2][y1 - 1] - s[x1 - 1][y2] + s[x1 - 1][y1 - 1];printf("%lld\n", sum); // 输出子矩阵的和}return 0; // 主函数返回0,表示程序正常结束
}

简洁版

#include<stdio.h>
long long a[5010][5010], s[5010][5010];
int main()
{long long int n, m, q;scanf("%lld%lld%lld", &n, &m, &q);for (int i = 1; i <= n; i++)for (int j = 1; j <= m; j++)scanf("%lld", &a[i][j]);for (int i = 1; i <= n; i++)for (int j = 1; j <= m; j++)s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j];while (q--){long long int x1, x2, y1, y2;scanf("%lld%lld%lld%lld", &x1, &y1, &x2, &y2);long long int sum = s[x2][y2] - s[x2][y1 - 1] - s[x1 - 1][y2] + s[x1 - 1][y1 - 1];printf("%lld\n", sum);}return 0;
}

 


二、题目描述

小明昨天晚上熬夜看小说结果穿越了,他来到一个神秘的大陆。此时,小明正在探索此地,发现这片大陆是由一个 n x m 的矩阵构成,每个位置上都有不同的土地信息。矩阵中的每个元素表示这个地方的价值,可能是金币、陷阱或者普通土地。

如果某个位置的值为正数,表示小明在这个地方获得了金币。
如果某个位置的值为负数,表示这个地方有陷阱,小明会丢失金币。
如果值为零,表示这是普通土地,没有金币也没有陷阱。
贪婪的小明想要在这片大陆上收集金币,于是他找上了你,并答应最终获得的金币分你不到1成。
 

你的程序需要帮他计算出在一个子矩阵内能获得金币数量的总和,如果金币数量小于0,则直接输出0,否则输出金币数量。

输入

第一行包含两个整数 n 和 m,表示大陆的行数和列数(1 <= n, m <= 1000) 
接下来 n 行,每行包含 m 个整数,表示大陆的土地价值。值为正表示金币,值为负表示陷阱,值为零表示普通土地(-1000 <= 价值 <= 1000)
接下来一个整数 q,表示查询的次数 (1 <= q <= 1000)
接下来 q 行,每行包含四个整数 x1, y1, x2, y2,表示查询的子矩阵区域,其中 (x1, y1) 和 (x2, y2) 是该子矩阵的左上角和右下角坐标(注意坐标从 1 开始,且保证 1 <= x1 <= x2 <= n 且 1 <= y1 <= y2 <= m)

输出

对于每个查询,输出一个整数,表示该子矩阵内的金币和。(如果金币数量小于0,则直接输出0)

样例输入 
4 5
1 2 3 4 5
-1 2 -2 3 4
5 -1 3 -2 6
7 8 9 10 -3
3
1 1 2 3
2 2 4 5
1 1 4 5
样例输出 
5
37
63

题目代码

解析版

#include<stdio.h> int a[1010][1010], s[1010][1010]; // 定义两个二维数组a和s,a用于存储输入的矩阵,s用于存储前缀和矩阵int main(){ int m, n, j, i, q, x1, x2, y1, y2, h=0; scanf("%d%d", &n, &m); // 读取矩阵的行数n和列数m// 读取矩阵a的元素for (i = 1; i <= n; i++){for (j = 1; j <= m; j++){scanf("%d", &a[i][j]); }}// 计算前缀和矩阵sfor (i = 1; i <= n; i++){for (j = 1; j <= m; j++){s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j]; // 根据前缀和的定义计算s[i][j]}}scanf("%d", &q); // 读取查询次数q// 处理每个查询for (i = 1; i <= q; i++){h = 0; // 重置h为0,用于存储当前查询的子矩阵和scanf("%d%d%d%d", &x1,&y1,&x2,&y2); // 读取查询的子矩阵的左上角坐标(x1,y1)和右下角坐标(x2,y2)// 根据前缀和的性质计算子矩阵的和h += s[x2][y2] - s[x1 - 1][y2] - s[x2][y1 - 1] + s[x1-1][y1-1]; //一定一定不要忘记加上多减的那一部分// 如果子矩阵的和大于0,则输出h,否则输出0if (h > 0)printf("%d\n", h);else printf("0\n"); //一定一定不要忘记在0后边加上换行符\n 不然就不能全对哦}return 0; 
}

简洁版

#include<stdio.h>
int a[1010][1010], s[1010][1010];
int main(){int m, n, j, i, q, x1, x2, y1, y2, h=0;scanf("%d%d", &n, &m);for (i = 1; i <= n; i++){for (j = 1; j <= m; j++){scanf("%d", &a[i][j]);}}for (i = 1; i <= n; i++){for (j = 1; j <= m; j++){s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j];}}scanf("%d", &q);for (i = 1; i <= q; i++){h = 0;scanf("%d%d%d%d", &x1,&y1,&x2,&y2);h += s[x2][y2] - s[x1 - 1][y2] - s[x2][y1 - 1] + s[x1-1][y1-1];if (h > 0)printf("%d\n", h);else printf("0\n");}return 0;
}


总结

 // 根据前缀和的定义计算s[i][j]  s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j];

// 利用前缀和矩阵s计算子矩阵的和 sum = s[x2][y2] - s[x2][y1 - 1] - s[x1 - 1][y2] + s[x1 - 1][y1 - 1];

洛谷U388817

http://www.lryc.cn/news/502117.html

相关文章:

  • SRS 服务器入门:实时流媒体传输的理想选择
  • 【ETCD】【源码阅读】configurePeerListeners() 函数解析
  • 1_ssrf总结
  • 深入解析 Redis
  • Visual Studio 2022发布UWP应用证书绑定失败
  • K8S对接ceph的RBD块存储
  • ragflow连不上ollama的解决方案
  • ACL与Prefix List(前缀列表)
  • OpenSSH和OpenSSL升级
  • 数据库继续学习
  • 车载以太网-UDPNM
  • 网页核心页面设计(第8章)
  • 在PowerShell下运行curl命令出现错误:Invoke-WebRequest : 无法处理参数,因为参数名称“u”具有二义性
  • 医疗花费预测——协方差矩阵和热力图
  • react antd tabs router 基础管理后台模版
  • 【数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
  • 【数据结构——栈与队列】链栈的基本运算(头歌实践教学平台习题)【合集】
  • GIT CLONE ERROR: remote: [session-ec426a86] Access denied
  • GitHub 正式收录 MoonBit 作为一门通用编程语言!核心用户突破三万!
  • PHP中GD库的使用
  • docker安装Elasticsearch和Kibana
  • 【Linux】文件管理必备知识和基本指令
  • 欢迪迈手机商城设计与实现
  • 量化交易系统开发-实时行情自动化交易-3.4.2.3.数字货币市场深度数据
  • 有序集合ZSET【Redis对象篇】
  • 力扣-图论-9【算法学习day.59】
  • 如何选择安全、可验证的技术?
  • Allure在自动化测试中的应用
  • C# 探险之旅:第十一节 - 循环(foreach):一场“遍历”奇幻岛的大冒险!
  • Ubuntu24.04配置STMTrack