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

CCF-CSP 2024 --重塑矩阵1,2c语言题解

  创作想法是因为像我当初大一时候想参加一些比赛但是奈何只学了c和c相关数据结构,但是对于许多竞赛的题目的题解往往都是c++或者其他面向对象的编程语言,让我们难以在c语言基础上入手这些比较复杂的题目。

  创造的目的是为了帮助各位同时提高我对c语言编程的理解和锻炼个人能力,废话不多说上菜!!

1.矩阵重塑(其一)

刷新 

时间限制: 1.0 秒

空间限制: 512 MiB

相关文件: 题目目录(样例文件)

题目背景

矩阵(二维)的重塑(reshape)操作是指改变矩阵的行数和列数,同时保持矩阵中元素的总数不变。

题目描述

矩阵的重塑操作可以具体定义为以下步骤:

设原矩阵为 𝑀M,其维度为 𝑛×𝑚n×m,即有 𝑛n 行和 𝑚m 列。新矩阵为 𝑀′M′,其维度为 𝑝×𝑞p×q。重塑操作要满足 𝑛×𝑚=𝑝×𝑞n×m=p×q,这保证了元素的总数不变。

  1. 线性化原矩阵:按照行优先的顺序,将原矩阵 𝑀M 的元素转换成一个长度为 𝑛×𝑚n×m 的一维数组 𝐴A。这意味着你先读取 𝑀M 的第 00 行元素,然后是第 11 行,依此类推,直到最后一行。
  2. 填充新矩阵:使用一维数组 𝐴A 中的元素按照行优先的顺序填充新矩阵 𝑀′M′。首先填充 𝑀′M′ 的第 00 行,直到该行有 𝑞q 个元素,然后继续填充第 11 行,直到所有 𝑝p 行都被填满。

给定原矩阵中的一个元素的位置 (𝑖,𝑗)(i,j)(0≤𝑖<𝑛0≤i<n 且 0≤𝑗<𝑚0≤j<m),我们可以找到这个元素在被线性化后的一维数组 𝐴A 中的位置 𝑘k(0≤𝑘<𝑛×𝑚0≤k<n×m),然后确定它在新矩阵 𝑀′M′ 中的位置 (𝑖′,𝑗′)(i′,j′)(0≤𝑖′<𝑝0≤i′<p 且 0≤𝑗<𝑞0≤j<q)。它们之间满足如下数学关系:𝑖×𝑚+𝑗=𝑘=𝑖′×𝑞+𝑗′i×m+j=k=i′×q+j

给定 𝑛×𝑚n×m 的矩阵 𝑀M 和目标形状 𝑝p、𝑞q,试将 𝑀M 重塑为 𝑝×𝑞p×q 的矩阵 𝑀′M′。

输入格式

从标准输入读入数据。

输入共 𝑛+1n+1 行。

输入的第一行包含四个正整数 𝑛n、𝑚m 和 𝑝p、𝑞q

接下来依次输入原矩阵 𝑀M 的第 00 到第 𝑛−1n−1 行,每行包含 𝑚m 个整数,按列下标从 00 到 𝑚−1m−1 的顺序依次给出。

输出格式

输出到标准输出。

输出共 𝑝p 行,每行 𝑞q 个整数,表示重塑后的矩阵 𝑀′M′。输出格式与输入相同,即依次输出 𝑀′M′ 的第 00 行到第 𝑝−1p−1 行;行内按列下标从 00 到 𝑞−1q−1 的顺序输出,且两个整数间仅用一个空格分隔。

样例1输入

2 3 3 2
1 2 3
4 5 6

样例1输出

1 2
3 4
5 6

样例2输入

2 2 1 4
6 6
6 6

样例2输出

6 6 6 6

子任务

全部的测试数据满足:

  • 𝑛n、𝑚m 和 𝑝p、𝑞q 均为正整数且 𝑛×𝑚=𝑝×𝑞≤104n×m=p×q≤104;
  • 输入矩阵中每个元素的绝对值不超过 10001000。

来自 <TUOJ>

tip:上面看不请 我在单独拿出来 

主函数部分------

具体函数部分--------

然后实现功能 即可通过:

下面是完整代码:

#include<stdlib.h>
#include<stdio.h>int** RecreatMatrix(int** a, int n, int m, int p, int q)
{// 变量初始  int* tmp = (int*)malloc(n*m*sizeof(int));// 中间矩阵int size = 0;// for (int i = 0; i < n; i++){for (int j = 0; j < m; j++){tmp[size++]=a[i][j];}}// 创建目标矩阵 obj int** obj = (int**)malloc(p * sizeof(int*));for (int i = 0; i < p; i++){obj[i] = (int*)malloc(q * sizeof(int));}// 存放元素吧for (int i = 0; i < n; i++){free(a[i]);}free(a);int x = 0;for (int i = 0; i < p; i++){for (int j = 0; j < q; j++){obj[i][j] = tmp[x];x++;}}return obj;
}int main()
{int n = 0;int m = 0;int p = 0;int q = 0;scanf("%d %d %d %d",&n,&m,&p,&q);int** matrix = (int**)malloc( n*sizeof(int*));for (int i = 0;i < n; i++){matrix[i] = (int*)malloc(m*sizeof(int));}for (int i = 0; i < n; i++){for (int j = 0; j < m; j++){scanf("%d", &matrix[i][j]);}}// 调用函数 更改行和列 matrix = RecreatMatrix(matrix,n, m, p, q);for (int i = 0; i < p; i++){for (int j = 0; j < q; j++){printf("%d ", matrix[i][j]);}printf("\n");}//确保严谨 记得销毁哦 遍历的类似思路可以拿过来for (int i = 0; i < p; i++){free(matrix[i]);}free(matrix);matrix = NULL;return 0;
}

2.重塑矩阵二----依然动态实现

时间限制: 1.0 秒

空间限制: 512 MiB

相关文件: 题目目录(样例文件)

题目背景

矩阵转置操作是将矩阵的行和列交换的过程。在转置过程中,原矩阵 𝐴A 的元素 𝑎𝑖𝑗aij 会移动到转置后的矩阵 𝐴𝑇AT 的 𝑎𝑗𝑖aji 的位置。这意味着 𝐴A 的第 𝑖i 行第 𝑗j 列的元素在 𝐴𝑇AT 中成为了第 𝑗j 行第 𝑖i 列的元素。

例如,有矩阵 𝐴A 如下:

𝐴=[𝑎𝑏𝑐𝑑𝑒𝑓]A=[adbecf]

它的转置矩阵 𝐴𝑇AT 会是:

𝐴𝑇=[𝑎𝑑𝑏𝑒𝑐𝑓]AT=abcdef​​

矩阵转置在线性代数中是一个基本操作,广泛应用于各种数学和工程领域。

题目描述

给定 𝑛×𝑚n×m 的矩阵 𝑀M,试编写程序支持以下查询和操作:

  1. 重塑操作 𝑝p𝑞q:将当前矩阵重塑为 𝑝×𝑞p×q 的形状(重塑的具体定义见上一题);
  2. 转置操作:将当前矩阵转置;
  3. 元素查询 𝑖i𝑗j:查询当前矩阵第 𝑖i 行 𝑗j 列的元素(0≤𝑖<𝑛0≤i<n 且 0≤𝑗<𝑚0≤j<m)。

依次给出 𝑡t 个上述查询或操作,计算其中每个查询的结果。

输入格式

从标准输入读入数据。

输入共 𝑛+𝑡+1n+t+1 行。

输入的第一行包含三个正整数 𝑛n𝑚m 和 𝑡t

接下来依次输入初始矩阵 𝑀M 的第 00 到第 𝑛−1n−1 行,每行包含 𝑚m 个整数,按列下标从 00 到 𝑚−1m−1 的顺序依次给出。

接下来输入 𝑡t 行,每行包含形如 op a b 的三个整数,依次给出每个查询或操作。具体输入格式如下:

  • 重塑操作:1 p q
  • 转置操作:2 0 0
  • 元素查询:3 i j

输出格式

输出到标准输出。

每个查询操作输出一行,仅包含一个整数表示查询结果。

样例1输入

解释

3 2 3
1 2
3 4
5 6
3 0 1
1 2 3
3 1 2

样例1输出

2
6

样例2输入

解释

3 2 5
1 2
3 4
5 6
3 1 0
2 0 0
3 1 0
1 3 2
3 1 0

样例2输出

3
2
5

初始矩阵: [123456]135246​​, (1,0)(1,0) 位置元素为 33

转置后: [135246][123456], (1,0)(1,0) 位置元素为 22

重塑后: [135246]154326​​, (1,0)(1,0) 位置元素为 55

子任务

8080 的测试数据满足:

  • 𝑡≤100t≤100

全部的测试数据满足:

  • 𝑡≤105t≤105 且其中转置操作的次数不超过 100100
  • 𝑛n𝑚m 和所有重塑操作中的 𝑝p𝑞q 均为正整数且 𝑛×𝑚=𝑝×𝑞≤104n×m=p×q≤104
  • 输入矩阵中每个元素的绝对值不超过 10001000

提示

  • 对于 𝑛×𝑚n×m 的矩阵,虽然转置和重塑操作都可以将矩阵形态变为 𝑚×𝑛m×n,但这两种操作通常会导致不同的结果。
  • 评测环境仅提供各语言的标准库,特别地,不提供任何线性代数库(如 numpypytorch 等)。

来自 <TUOJ>

完整代码:

#include<stdlib.h>
#include<stdio.h>
int** RecreatMatrix(int** a, int n, int m, int p, int q)
{// 变量初始  int* tmp = (int*)malloc(n*m*sizeof(int));// 中间矩阵int size = 0;// for (int i = 0; i < n; i++){for (int j = 0; j < m; j++){tmp[size++]=a[i][j];}}// 创建目标矩阵 obj int** obj = (int**)malloc(p * sizeof(int*));for (int i = 0; i < p; i++){obj[i] = (int*)malloc(q * sizeof(int));}// 存放元素吧for (int i = 0; i < n; i++){free(a[i]);}free(a);int x = 0;for (int i = 0; i < p; i++){for (int j = 0; j < q; j++){obj[i][j] = tmp[x];x++;}}return obj;
}int** transpose(int** a, int n, int m)
{int p = m;int q = n;int** obj = (int**)malloc(p * sizeof(int*));for (int i = 0; i < p; i++){obj[i] = (int*)malloc(q * sizeof(int));}for (int i = 0; i < n; i++){for (int j = 0; j < m; j++){obj[j][i] = a[i][j];}}// 记得销毁哦for (int i = 0; i < n; i++){free(a[i]);}free(a);return obj;}// 查询功能
int Find_x(int** a,int i, int j)
{return a[i][j];
}int main()
{int n = 0;int m = 0;int t = 0;scanf("%d %d %d", &n, &m, &t);int** matrix = (int**)malloc(n * sizeof(int*));for (int i = 0; i < n; i++){matrix[i] = (int*)malloc(m * sizeof(int));}for (int i = 0; i < n; i++){for (int j = 0; j < m; j++){scanf("%d", &matrix[i][j]);}}// 进入功能使用部分while (t--){int input = 0;scanf("%d",&input);if (input == 1){int p = 0;int q = 0;scanf("%d %d", &p, &q);matrix = RecreatMatrix(matrix, n, m, p, q);n = p;m = q;}else if (input == 2){int p = 0;int q = 0;scanf("%d %d", &p, &q);matrix = transpose(matrix, n,  m);int tmp = n;n = m;m = tmp;}else if (input == 3){int i = 0;int j = 0;scanf("%d %d", &i, &j);int x = Find_x(matrix,i,j);printf("%d\n",x);}}for (int i = 0; i < n; i++){free(matrix[i]);}free(matrix);}

3. 思路的缺陷-----以及建议

缺陷

  (重塑矩阵二)简单发现代码提交之后会存在一些测试案例显示占用内存空间超出限制,这里我认为因为其中主要原因是因为:

  频繁使用malloc这样的动态内存分布函数使得堆上的内存使用free后内存碎片化,使得之后没有一块连续的足够大的内存存放数据。

  另一个缺陷就是我们使用malloc函数的时候都没有判空,其实严谨来说咱还是判空一下(读者自行解决咯)

建议

 其实我们可以创建静态矩阵来存放数据,初始化该矩阵直接最大值即可,然后开始实现吧。

我这里仅对重塑矩阵部分进行提示,其他部分都很简单大家自己想想吧。

  这里我们要用到数组指针。传递二维数组嘛

是吧更加简单明了。

  好的这期就到这里非常感谢各位的支持你的小红心就是对我最大的鼓励。谢谢咯

补充: 非常抱歉,经过我后面再度调试发现我们的动态其实能过。

之所以前面内存超载了,是因为我在一个重塑矩阵函数中忘记释放一个中间载体一维数组了。

修改之后就是加一个free(tmp)即可。

至于前面的建议也可以采纳,以及对于malloc的缺陷也可以了解一下我就不删除了。谢谢咯

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 网络编程9.3
  • 基础学习之——Kubernetes
  • vscode好用的快捷键整理~
  • 基础学习之——Docker Compose的安装和使用
  • 不管夫妻还是情人,想要长相厮守、生活幸福美满,就这两个字!
  • 宁波银行资产规模首超3万亿,高成长性被机构清一色看好
  • 维度不固定的多维数组形参笔记
  • Swift 运算符
  • spring boot 项目 prometheus 自定义指标收集区分应用环境集群实例ip,使用 grafana 查询--方法耗时分位数指标
  • HarmonyOS 开发范式、应用模型
  • Electron 项目实战 02:打包和自动更新
  • 有temp表包含A,B两列,使用SQL,对B列进行处理,形成C列,按A列顺序,B列值不变,则C列累计技术,B列值变化,则C列重新开始计数
  • 数据库课程设计mysql---图书管理系统详细的设计文档和需求文档
  • TCP如何关闭连接(详细版)
  • 如何进行 AWS 云监控
  • “寒冬”下的金三银四跳槽季来了,帮你客观分析一下局面
  • Angular数据绑定机制
  • centos安装java运行环境jdk+tomcat
  • mockjs让前端开发独立于后端
  • mysql外键的使用
  • RxJS 实现摩斯密码(Morse) 【内附脑图】
  • Twitter赢在开放,三年创造奇迹
  • vue-cli在webpack的配置文件探究
  • Vue全家桶实现一个Web App
  • webpack4 一点通
  • 基于webpack 的 vue 多页架构
  • 基于游标的分页接口实现
  • 记一次用 NodeJs 实现模拟登录的思路
  • 看域名解析域名安全对SEO的影响
  • 如何设计一个微型分布式架构?
  • 设计模式 开闭原则
  • 适配iPhoneX、iPhoneXs、iPhoneXs Max、iPhoneXr 屏幕尺寸及安全区域
  • 体验javascript之美-第五课 匿名函数自执行和闭包是一回事儿吗?
  • 通过获取异步加载JS文件进度实现一个canvas环形loading图
  • 王永庆:技术创新改变教育未来
  • 优秀架构师必须掌握的架构思维
  • 转载:[译] 内容加速黑科技趣谈
  • Oracle Portal 11g Diagnostics using Remote Diagnostic Agent (RDA) [ID 1059805.
  • 《TCP IP 详解卷1:协议》阅读笔记 - 第六章
  • ​​​​​​​​​​​​​​Γ函数
  • ​RecSys 2022 | 面向人岗匹配的双向选择偏好建模
  • ​低代码平台的核心价值与优势
  • ​如何在iOS手机上查看应用日志
  • #gStore-weekly | gStore最新版本1.0之三角形计数函数的使用
  • #NOIP 2014#Day.2 T3 解方程
  • #我与Java虚拟机的故事#连载13:有这本书就够了
  • (02)Hive SQL编译成MapReduce任务的过程
  • (1/2)敏捷实践指南 Agile Practice Guide ([美] Project Management institute 著)
  • (10)工业界推荐系统-小红书推荐场景及内部实践【排序模型的特征】
  • (3)Dubbo启动时qos-server can not bind localhost22222错误解决
  • (day 2)JavaScript学习笔记(基础之变量、常量和注释)
  • (JSP)EL——优化登录界面,获取对象,获取数据
  • (八)Spring源码解析:Spring MVC
  • (附源码)ssm考试题库管理系统 毕业设计 069043
  • (论文阅读30/100)Convolutional Pose Machines