1050 螺旋矩阵 (25 分)
本题要求将给定的 NNN 个正整数按非递增的顺序,填入“螺旋矩阵”。所谓“螺旋矩阵”,是指从左上角第 1 个格子开始,按顺时针螺旋方向填充。要求矩阵的规模为 m 行 n 列,满足条件:m×n 等于 NNN;m≥n;且 m−n 取所有可能值中的最小值。
输入格式:
输入在第 1 行中给出一个正整数 NNN,第 2 行给出 NNN 个待填充的正整数。所有数字不超过 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
代码
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
bool cmp (int a, int b) {
return a > b;
}
int N;
void solve () {
int A[N];
for (int i = 0; i < N; i++) {
scanf ("%d", &A[i]);
}
sort (A, A + N, cmp); //读完数排序
int m, n = (int)sqrt(1.0 * N);
while (N % n != 0) {
n--;
}
m = N / n; //得到要求的m*n矩阵
bool visited[m][n]; //记录数字是否加入矩阵
int ans[m][n]; //存储矩阵数字
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
visited[i][j] = false;
}
} //矩阵初始化
//接下来进行螺旋填充
int dx[4] = {0, 1, 0, -1}; //对应变换为右->下->左->上
int dy[4] = {1, 0, -1, 0}; //注意此处变化x,y的加或减或不变,不要搞错
int di = 0; //初始向右走,走到头或者是加入过了。则换下一个方向
int i = 0, j = 0, k = 0;
do {
ans[i][j] = A[k++];
visited[i][j] = true; //加入矩阵置为已加入
int newi = i + dx[di]; //变换后的x
int newj = j + dy[di]; //变换后的y
if (newi < 0 || newi >= m || newj < 0 || newj >= n || visited[newi][newj]) {
di = (di + 1) % 4; //下一个方向
}
i += dx[di]; //更新i, j
j += dy[di];
} while (k < N);
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
printf ("%d", ans[i][j]);
if (j < n-1) {
printf (" "); //空格
}
}
printf ("\n"); //跳至下一行
}
}
int main () {
scanf ("%d", &N);
solve ();
return 0;
}