这道题折腾了好久,最后发现不是二维矩阵的相关问题,而是一个很简单的小问题
接下来为列出遇到的各种问题,并逐个分析
本题涉及的新知识点:
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;
}
}