题目见这里
题意是比较清晰的,即给一串正数,按降序填充一个螺旋矩阵,矩阵大小取决于正数个数。
确定矩阵行和列很容易,主要是找到填充规律,我们借用下面的三张图很容易发现规律。
我们只要用turnH和turnV记载水平方向和竖直方向转换次数,并单独处理第一行和最后一个数就好啦。
代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAXN 100005
#define M 405
#define N 405
int Cmp(const void *a, const void *b){ //desending
return *(int *)b - *(int *)a;
}
int main(){
// freopen("Data.txt","r",stdin);
int num,m,n,k,move,moveable,step,dir,turnH,turnV,row,col;
int seq[MAXN],spiral_mat[M][N];
scanf("%d",&num);
for(k=0;k<num;k++) scanf("%d",&seq[k]);
qsort((void *)seq,num,sizeof(seq[0]),Cmp);
//find n、m
//反例:num=7
n=(int)sqrt(num);
m = num/n;
while(n*m!=num){ //or num%n!=0
n --;
m = num/n;
}
row = col = 1;
step=0;
turnV = turnH = 1;
//单独处理第一行
moveable = n-turnH;
dir = 1;
move = 0;
while(move<moveable){
spiral_mat[row][col+move] = seq[step++];
move ++;
}
col += moveable;
moveable = m-turnV;
while(moveable){
move = 0;
dir ++;
if(dir==1){ //Right
while(move<moveable){
spiral_mat[row][col+move] = seq[step++];
move ++;
}
col += moveable;
moveable = m-turnV;
turnH ++;
}
else if(dir==2){ //Down
while(move<moveable){
spiral_mat[row+move][col] = seq[step++];
move ++;
}
row += moveable;
moveable = n-turnH;
turnV ++;
}
else if(dir==3){ //Left
while(move<moveable){
spiral_mat[row][col-move] = seq[step++];
move ++;
}
col -= moveable;
moveable = m-turnV;
turnH ++;
}
else{ //Up
while(move<moveable){
spiral_mat[row-move][col] = seq[step++];
move ++;
}
row -= moveable;
moveable = n-turnH;
turnV ++;
dir = 0;
}
}
//最后一个位置单独处理
spiral_mat[row][col] = seq[step];
for(row=1;row<=m;row++)
for(col=1;col<=n;col++){
printf("%d",spiral_mat[row][col]);
if(col<n) printf(" ");
else printf("\n");
}
return 0;
}