本题要求将给定的 N 个正整数按非递增的顺序,填入“螺旋矩阵”。所谓“螺旋矩阵”,是指从左上角第 1 个格子开始,按顺时针螺旋方向填充。要求矩阵的规模为 m 行 n 列,满足条件:m×n 等于 N;m≥n;且 m−n 取所有可能值中的最小值。
输入格式:
输入在第 1 行中给出一个正整数 N,第 2 行给出 N 个待填充的正整数。所有数字不超过 10
4
,相邻数字以空格分隔。
输出格式:
输出螺旋矩阵。每行 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
思路:
先将N个数按从大到小排序,然后从根号N开始递减寻找第一个满足m×n 等于 N和m≥n条件m和n,此时m-n最小,用int型变量i、j代表当前在矩阵的位置,放数的时候按照右下左上顺序放,依次用while循环判断是否同时满足此位置未赋值并且未超出边界
C++代码:
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
bool cmp(int a,int b){
return a>b
}
int main(){
int N,n,m;
scanf("%d",&N);
int a[N];
for(int i=0;i<N;i++){
scanf("%d",&a[i]);
}
sort(a,a+N,cmp);//从大到小排序;
for(n=(int)sqrt(N*1.0);n>=0;n--){//sqrt内需要是double类型,所以乘以1.0
if(N%n==0){ //让n从根号N开始递减,这样找到m,n时可以满足m>=n
m=N/n;
break;
}
}
int arr[m][n];//要填充的数组
for(int i=0;i<m;i++) {
for(int j=0;j<n;j++){
arr[i][j]=0;
}
}
int i=0,j=0,k=0;
arr[i][j]=a[k++];
while(k<N){
while(j+1<n&&!arr[i][j+1]){向右, 满足小于边界和未赋值过则赋值
j=j+1;
arr[i][j]=a[k++];
}
while(i+1<m&&!arr[i+1][j]){//向下,满足 小于边界和未赋值,则赋值
i=i+1;
arr[i][j]=a[k++];
}
while(j-1>=0&&!arr[i][j-1]){//向左
j=j-1;
arr[i][j]=a[k++];
}
while(i-1>=0&&!arr[i-1][j]){//向上
i=i-1;
arr[i][j]=a[k++];
}
}
for(int ii=0;ii<m;ii++){
for(int jj=0;jj<n;jj++){
printf("%d",arr[ii][jj]);
if(jj!=n-1){
printf(" ");
}
}
printf("\n");
}
}