[PAT-A 1105]Spiral Matrix

在这里插入图片描述
题目大意:
将给定的N个正整数按非递增的顺序,填入螺旋矩阵,所螺旋矩阵,就是从左上第一个给开始,按顺时针方向填充。要求矩阵的规模为m行n列。
满足条件,m*n等于N,m>=n,取m-n中最小值。

思路:
1)题目要求按非递增的顺序,因此先对数组排序,从大到小。
2)m与n的确定,m与n一定是N的约数,且m>=n,所以m必须是不小于sqrt(N)的最小整数,因此让m从sqrt(N)向上递增,直到N%m==0,此时n=N/m。
3)对螺旋矩阵的赋值以圈为单位进行,即每次先填完外面一圈逐渐向里面的圈填,直到填充个数等于N,设置上下左右四个边界,UDLR。对每一层,从左上角开始填,先向右,到达右边界,再向下,达到下边界,再向左,到达左边界,再向上,到达上边界。至此填完一圈,UDLR各减一,(向里进一层)依次类推。指针重新定位到里面一层的左上角。
4)当N是完全平方数时最里面一层只有一个数,需要特判。N如果是素数,只有一列,此时行数为N,列数最多sqrt(N)。

AC代码:

//PAT_A 1105
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn = 10010;
int matrix[maxn][maxn], A[maxn];
bool cmp(int a, int b) {
	return a > b;
}
int main() {
	int N, m, n;
	(void)scanf("%d", &N);
	for (int i = 0; i < N; i++) {
		(void)scanf("%d", &A[i]);
	}
	if (N == 1) {
		printf("%d", A[0]);
		return 0;
	}
	sort(A, A + N, cmp);
	m = (int)ceil(sqrt(1.0 * N));
	while (N % m != 0)m++;
	n = N / m;
	int u = 1, d = m, l = 1, r = n;//边界
	int i = 1, j = 1, now = 0;
	while (now < N) {
		while (now < N && j < r) {//向右
			matrix[i][j] = A[now++];
			j++;
		}
		while (now < N && i < d) {//向下
			matrix[i][j] = A[now++];
			i++;
		}
		while (now < N && j > l) {//向左
			matrix[i][j] = A[now++];
			j--;
		}
		while (now < N && i > u) {//向上
			matrix[i][j] = A[now++];
			i--;
		}
		i++; j++; u++; d--; l++; r--;//缩小边界,移动指针
		if (now == N - 1)matrix[i][j] = A[now++];
	}
	for (int i = 1; i <= m; i++) {
		for (int j = 1; j <= n; j++) {
			printf("%d", matrix[i][j]);
			if (j < n)printf(" ");
			else printf("\n");
		}
	}
	return 0;
}

发布了157 篇原创文章 · 获赞 1 · 访问量 6062

猜你喜欢

转载自blog.csdn.net/weixin_44699689/article/details/104728487