计蒜客 | 幻方矩阵题解和相关知识点 | 数组

Cora这条鱼,终于在大佬的帮助下过了,555

  • 题目概述
    总的来说就是关于矩阵处理的题目,不过不同的是题目有限制条件,所以直接暴力换位置会有内存超限和超时问题,这里我们就要换一种思路来将他们换掉。
    首先我们来看一下题目
    在这里插入图片描述- 题目分析
    看到这个是不是很熟悉的感觉,矩阵交换,直接换换换,小case,可是写着写着你就崩了。。因为换的数很大,所以暴力解决不了555
    1.内存超限的问题:最常用的处理矩阵的数据结构是普通的数组,但是为了保证能够收集到所有的矩阵数据,题目要求为10^6, 数组在刚开始就申请了较大的空间,会导致程序运行过程中会有一部分浪费的内存,这个时候平台就出现了心碎的声音= =,内存占比太大导致内存超限程序无法正常运行。
    关于数组这一部分,vector——作为一种可以根据元素的输入申请空间的数组类型,就是很方便的解决方案。
    下面代码段只是部分内容的讲解,不是最终解法哦。
//最基本的,使用vector要先在把<vector>的库包含进来。
#include<iostream>
#include<vector>
using namespace std;
//然后定义一个vector的二维数组
vector<vector<int>> a(n);//表示提前声明了有n个一维数组
//然后在输入数据的时候,对应每个一维数组(即矩阵的行)当中有几个元素就输入几个,申请相应大小的内存
for (int i = 0; i < n; i++)
	for (int j = 0; j < m; j++)
	{
		cin >> tmp;
		a[i].push_back(tmp);//把输入的元素存入vector数组里
	}

然后把普通数组改成了vector之后,我快乐的去准备AC的音乐声,结果又心碎了· · ·,好吧,暴力交换位置也不行,不仅会导致内存问题,而且会拖长运行的时间,可能导致运行时间太长。
2.矩阵元素位置置换处理
所以采用标记矩阵行列来处理两个一维数组row, col的方式来替代。
注意,这里也用new来申请动态数组比较保险。
用row和col来保存操作的顺序,这样就不需要一个一个来操作矩阵中的元素,只需要在打印的时候按行列替换之后的形式输出就行了。

//矩阵行列定义和初始化
	int *row = new int[n];
	int *col = new int[m];
	for (int i = 0; i < n; i++)
		row[i] = i;
	for (int j = 0; j < m; j++)
		col[j] = j;
//关键部分,交换矩阵行列顺序
	while (op--)
	{
		cin >> x >> y >> z;
		y--, z--;
		if (x == 0)//y,z行交换 
		{
			tmp = row[y];
			row[y] = row[z];
			row[z] = tmp;
		}
		else//y,z列交换 
		{
			tmp = col[y];
			col[y] = col[z];
			col[z] = tmp;
		}
	}
//打印交换后的矩阵
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < m; j++)
		{
			cout << a[row[i]][col[j]];//注意按照交换后行和列的位置来打印元素!
			if (j < m - 1)
				cout << " ";
		}
		cout << endl;
	}

总的来说,这个题没有很多内容,就是把暴力交换元素,换成了记录操作最后按操作后的元素顺序输出。这不仅减少了内存占用,也提高了程序的运行速度。

  • 代码片段
#include<iostream>
#include<vector>
using namespace std;
int main()
{
//数据定义 
	int n, m, op;
	//a.resize(n, vector<int>(m));
	int x;//操作的类型
	int y, z;//执行操作的行或列
	int tmp;//中间过渡参数 
//输入矩阵、操作 
	cin >> n >> m;//矩阵大小n*m
	vector<vector<int>> a(n);
	for (int i = 0; i < n; i++)
		for (int j = 0; j < m; j++)
		{
			cin >> tmp;
			a[i].push_back(tmp);//输入矩阵元素 
		}
//矩阵行列定义和初始化
	int *row = new int[n];
	int *col = new int[m];
	for (int i = 0; i < n; i++)
		row[i] = i;
	for (int j = 0; j < m; j++)
		col[j] = j;
	cin >> op;//操作次数op 
//执行操作 
	while (op--)
	{
		cin >> x >> y >> z;
		y--, z--;
		if (x == 0)//y,z行交换 
		{
			tmp = row[y];
			row[y] = row[z];
			row[z] = tmp;
		}
		else//y,z列交换 
		{
			tmp = col[y];
			col[y] = col[z];
			col[z] = tmp;
		}
	}
//打印交换后的矩阵
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < m; j++)
		{
			cout << a[row[i]][col[j]];
			if (j < m - 1)
				cout << " ";
		}
		cout << endl;
	}
	delete row, col;
	system("pause");
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值