1050 螺旋矩阵 (25 分)
本题要求将给定的 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
我的代码:
#include<stdio.h>
#include<stdlib.h>
typedef struct{
int num, x, y;
}nstr;
int cmp(const void *a, const void *b);
int cmpx(const void *a, const void *b);
int cmpy(const void *a, const void *b);
int main(){
int n, i, j, k, x0, y0, min, flg;
scanf("%d", &n);
nstr a[n];
for(i=0;i<n;i++){
scanf("%d", &a[i].num);
a[i].x = 0;
a[i].y = 0;
}
qsort(a, n, sizeof(nstr), cmp);
min = n;
for(flg=n;flg&&flg>=n/flg;flg--){
/****************************************************************************************
如果只有一个数字,这里的循环会出现flg=0的情况,此时会有浮点错误,因此在循环判断中先加入对flg的判断
****************************************************************************************/
if(n%flg == 0 && (flg - n / flg) < min){
x0 = flg;
y0 = n / flg;
min = x0 - y0;
}
}
int ret1 = 1, ret2 = y0, ret3 = x0, ret4 = 1;//分别代表输出矩阵中4个顶点
j = k = 1;
for(i=0;i<n;i++){//给每个元素定位(x,y)
a[i].x = j;
a[i].y = k;
if(j == ret1 && k < ret2){
k++;
if(k==ret2)
ret1++;
}
else if(k == ret2 && j < ret3){
j++;
if(j==ret3)
ret2--;
}
else if(j == ret3 && k > ret4){
k--;
if(k==ret4)
ret3--;
}
else if(k == ret4 && j > ret1){
j--;
if(j==ret1)
ret4++;
}
}
qsort(a, n, sizeof(nstr), cmpx); //全部按照横坐标x排序
for(i=0;i<=n-y0;i+=y0){ //横坐标相同的y0个,每组按照纵坐标排序
qsort(a+i, y0, sizeof(nstr), cmpy);
}
for(i=0;i<n;i++){
(i+1)%y0 == 0 ? printf("%d\n", a[i].num) : printf("%d ", a[i].num);
}
return 0;
}
int cmp(const void *a, const void *b){
nstr t1 = *(nstr *)a;
nstr t2 = *(nstr *)b;
return t1.num < t2.num ? 1 : 0;
}
int cmpx(const void *a, const void *b){
nstr t1 = *(nstr *)a;
nstr t2 = *(nstr *)b;
return t1.x > t2.x ? 1 : 0;
}
int cmpy(const void *a, const void *b){
nstr t1 = *(nstr *)a;
nstr t2 = *(nstr *)b;
return t1.y > t2.y ? 1 : 0;
}
结果: