PAT1050_乙级_螺旋矩阵

15 篇文章 2 订阅
博客详细记录了一位程序员在解决C++编程问题时遇到的挑战,包括二维数组的动态创建、快速排序的实现以及在处理过程中遇到的错误和解决方案。博主分享了从二维数组的动态分配内存到使用自定义比较函数进行降序排序的步骤,并重点分析了在确定矩阵行列时的逻辑错误及修正方法。文章还包含了完整的错误代码和修复后的代码示例,对于学习C++编程和数组操作具有参考价值。
摘要由CSDN通过智能技术生成

这道题折腾了好久,最后发现不是二维矩阵的相关问题,而是一个很简单的小问题

接下来为列出遇到的各种问题,并逐个分析

本题涉及的新知识点:

1.关于c语言函数在c++中的调用(头文件)

#include<cstdio>

cstdio: 将stdio.h的内容用c++的头文件形式表现出来

标准输入输出:standard buffered intput&&output

2.二维数组的动态建立与快速排序

动态建立:

先创建二维指针,并申请第一维的动态空间(所申请空间储存的数据类型: int*)

=> 通过第一次循环,为第二维申请动态空间(所申请空间储存的数据类型: int)

=> 通过第二次循环,对最终的二维变量完全体进行操作

int** num = new int* [a];
for (int i = 0; i < a; i++) {
    num[i] = new int[b];
    for (int j = 0; j < b; j++) {
        cin >> num[i][j];
    }
}

此外,还可以使用vector容器及头文件#include<vector>附带的函数进行二维数组的动态建立

快速排序:

一般遇到使用sort函数,都是一维数组

sort函数的语法: sort(taget.begin(), taget.end(), cmp);

对象为二维数组时:

int cmp(int a, int b) {
	return a > b;
}

sort(num, num + n, cmp);

本题需求为降序排序,而sort函数默认为升序排序,在不使用c++模板函数great<int>less<int>的情况下,使用自定义函数cmp来控制数组升降

对比显然可得,二维与一维在快速排序上,命令基本雷同

编译与调试过程遇到的问题:

1.一维数组储存数列,并使用二维数组对数值位置进行处理

遇到的问题:处理代码及二维数组动态建立

2.格式问题   主要集中在测试点1 3 7

这个困扰很久,可能那天脑子瓦特了(对以后复习的自己来说,就是那天了(灬°ω°灬) )

以下附上错误代码:

#include<iostream>
using namespace std;
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
int cmp(int a, int b) {
	return a > b;
}
int main() {
	int n;
	cin >> n;
	int a = 0, b = 0;
	//行与列的计算  错误出现在这里
	for (int i = sqrt(double(n)) + 1; i > 0; i--) {
		if (n % i == 0) {
			//错误原因:如果那个可以被整除的i是1,那么break后,a=i(小),显然不符合行大于列的要求
			//从而造成格式错误
			a = i;
			b = n / i;
			break;
		}
	}
	//一维数组的建立,用于储存数据和第一次快排
	int* num = new int[n];
	for (int i = 0; i < n; i++) {
		cin >> num[i];
	}
	sort(num, num + n, cmp);
	//二维数组的建立,用于提取一维数组数据和螺旋矩阵的位置布置
	int** num1 = new int* [a];
	for (int i = 0; i < a; i++) {
		num1[i] = new int[b];
		for (int j = 0; j < b; j++) {
			num1[i][j] = 0;
		}
	}
	//排兵布阵的核心代码命令
	int x = 0, y = 0;
	num1[0][0] = num[0];
	int k = 0;
	while (k < n - 1) {
		while (y + 1 < b && !num1[x][y + 1] && k < n - 1) {
			num1[x][++y] = num[++k];
		}
		while (x + 1 < a && !num1[x + 1][y] && k < n - 1) {
			num1[++x][y] = num[++k];
		}
		while (y > 0 && !num1[x][y - 1] && k < n - 1) {
			num1[x][--y] = num[++k];
		}
		while (x > 0 && !num1[x - 1][y] && k < n - 1) {
			num1[--x][y] = num[++k];
		}
	}
	//将命令结果呈现到显示屏上
	for (int i = 0; i < a; i++) {
		for (int j = 0; j < b; j++) {
			cout << num1[i][j];
			if (j != b - 1) {
				cout << " ";
			}
		}
		cout << endl;
	}
}

错误信息:

 错误代码提取及改进:

错误代码提取:

//行与列的计算  错误出现在这里
for (int i = sqrt(double(n)) + 1; i > 0; i--) {
	if (n % i == 0) {
		//错误原因:如果那个可以被整除的i是1,那么break后,a=i(小),显然不符合行大于列的要求
		//从而造成格式错误
		a = i;
		b = n / i;
		break;
	}
}

代码改进及错误分析:

//显然,整数的两个因数应以平方根为对称轴,成左右对称,此消彼长
//之前的错误原因是将a与b与i的大小与对应关系弄混了
//i值两种可能: 
//1.n为完全平方数,a = b
//2.n开方后去零化整,i值小于真正的平方根,即这个i应该是列,即b,行a为n/i(别弄反了)
for (int i = sqrt((double)n); i >= 1; i--) {
	if (n % i == 0) {
		a = n / i;
		b = i;
		break;
	}
}

正确代码:

#include<iostream>
using namespace std;
#include<string.h>
#include<math.h>
#include<algorithm>
int cmp(int a, int b) {
	return a > b;
}
int main() {
	int n;
	cin >> n;
	int a = 0, b = 0;
	//破防bug起源地
	//行与列的确认
	for (int i = sqrt((double)n); i >= 1; i--) {
		if (n % i == 0) {
			a = n / i;
			b = i;
			break;
		}
	}
	//一维数组的建立,用于储存数据和第一次快排
	int* num = new int[n];
	for (int i = 0; i < n; i++) {
		cin >> num[i];
	}
	sort(num, num + n, cmp);
	//二维数组的建立,用于提取一维数组数据和螺旋矩阵的位置布置
	int** num1 = new int* [a];
	for (int i = 0; i < a; i++) {
		num1[i] = new int[b];
		for (int j = 0; j < b; j++) {
			num1[i][j] = 0;
		}
	}
	//排兵布阵的核心代码命令
	int x = 0, y = 0;
	num1[0][0] = num[0];
	int k = 0;
	while (k < n - 1) {
		while (y + 1 < b && !num1[x][y + 1] && k < n - 1) {
			num1[x][++y] = num[++k];
		}
		while (x + 1 < a && !num1[x + 1][y] && k < n - 1) {
			num1[++x][y] = num[++k];
		}
		while (y > 0 && !num1[x][y - 1] && k < n - 1) {
			num1[x][--y] = num[++k];
		}
		while (x > 0 && !num1[x - 1][y] && k < n - 1) {
			num1[--x][y] = num[++k];
		}
	}
	//将命令结果呈现到显示屏上
	for (int i = 0; i < a; i++) {
		for (int j = 0; j < b; j++) {
			cout << num1[i][j];
			if (j != b - 1) {
				cout << " ";
			}
		}
		cout << endl;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值