【练习】PAT 乙 1050 螺旋矩阵

题目

本题要求将给定的N个正整数按非递增的顺序,填入“螺旋矩阵”。所谓“螺旋矩阵”,是指从左上角第1个格子开始,按顺时针螺旋方向填充。要求矩阵的规模为m行n列,满足条件:m*n等于N;m>=n;且m-n取所有可能值中的最小值。

输入格式:

输入在第1行中给出一个正整数N,第2行给出N个待填充的正整数。所有数字不超过104,相邻数字以空格分隔。

输出格式:

输出螺旋矩阵。每行n个数字,共m行。相邻数字以1个空格分隔,行末不得有多余空格。

输入样例:

12

37 76 20 98 76 42 53 95 60 81 58 93

输出样例:

98 95 93

42 37 81

53 20 76

58 60 76

来源:PAT 乙 1050 螺旋矩阵


思路(注意事项)

【练习】PAT 乙 1050 螺旋矩阵_第1张图片
插一张柳神的图,无敌。

需要注意的几个点:

  • m和 列n 的求法。需要用到sqrt函数。函数要求传入的参数为 double 类型。要是传入其他类型的参数,就需要进行类型转换。若直接把整数类型(像 int)的 N 传入 sqrt 函数,编译器会隐式地把 N 转换为 double 类型。不过,为了避免隐式类型转换可能带来的潜在问题,同时增强代码的可读性与可维护性,建议进行显式的类型转换
  • 定义动态二维数组的方式。
  • level的层数要分奇偶性。

纯代码

#include

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

int main(){
	int N, t = 0;
	cin >> N;
	
	vector<int> a(N);
	for (int i = 0; i < N ; i++) cin >> a[i];
	sort (a.begin(), a.end(), cmp);
	
	int n = sqrt((double(N))), m;
	for (;n >= 1 ; n --)
		if (N % n == 0) 
		{
			m = N / n;
			break;
		}
	
	
	int level = m % 2 == 0 ? m / 2 : m / 2 + 1;
	
	vector<vector<int>> b(m, vector<int>(n));
	for (int i = 0; i < level; i ++)
	{
		for (int j = i; j <= n - i - 1 && t < N; j ++) b[i][j] = a[t ++];
		for (int j = i + 1; j <= m - i - 2 && t < N; j ++) b[j][n - i - 1] = a[t ++];
		for (int j = n - 1 - i; j >= i && t < N; j --) b[m - 1 - i][j] = a[t ++];
		for (int j = m - i - 2; j >= i + 1 && t < N; j --) b[j][i] = a[t ++];
	}
	
	int flag = 1;
	for (int i = 0; i < m; i ++)
		for (int j = 0; j < n ; j ++)
		{
			if (flag == 0) cout << " ";
			else flag = 0;
			cout << b[i][j];
			if (j == n - 1) 
			{
				flag = 1;
				cout << endl;
			}
		}
		
	return 0;
} 

题解(加注释)

#include
using namespace std;

// 自定义比较函数,用于降序排序
int cmp(int a, int b) {
    return a > b;
}

int main() {
    int N, t = 0; // N 是数组的长度,t 是数组 a 的索引
    cin >> N; // 输入数组的长度 N

    vector<int> a(N); // 定义数组 a,用于存储输入的数据
    for (int i = 0; i < N; i++) cin >> a[i]; // 输入数组元素

    // 对数组 a 进行降序排序
    sort(a.begin(), a.end(), cmp);

    // 找到满足 m * n = N 且 m >= n 的 m 和 n
    int n = sqrt((double(N))), m;
    for (; n >= 1; n--) {
        if (N % n == 0) { // 如果 n 是 N 的因数
            m = N / n; // 计算 m
            break;
        }
    }

    // 计算螺旋填充的层数
    int level = m % 2 == 0 ? m / 2 : m / 2 + 1;

    // 定义二维矩阵 b,大小为 m x n
    vector<vector<int>> b(m, vector<int>(n));

    // 螺旋填充二维矩阵
    for (int i = 0; i < level; i++) {
        // 从左到右填充上边
        for (int j = i; j <= n - i - 1 && t < N; j++)
            b[i][j] = a[t++];
        // 从上到下填充右边
        for (int j = i + 1; j <= m - i - 2 && t < N; j++)
            b[j][n - i - 1] = a[t++];
        // 从右到左填充下边
        for (int j = n - 1 - i; j >= i && t < N; j--)
            b[m - 1 - i][j] = a[t++];
        // 从下到上填充左边
        for (int j = m - i - 2; j >= i + 1 && t < N; j--)
            b[j][i] = a[t++];
    }

    // 输出二维矩阵
    int flag = 1; // 用于控制输出格式
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            if (flag == 0) cout << " "; // 控制输出格式,元素之间用空格分隔
            else flag = 0;
            cout << b[i][j]; // 输出矩阵元素
            if (j == n - 1) { // 每行输出结束后换行
                flag = 1;
                cout << endl;
            }
        }
    }

    return 0;
}

你可能感兴趣的:(PAT,题解,输入输出,矩阵,c++)