题目:
本题要求将给定的 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
这道题关键是找出螺旋变化的规律,然后按要求输出。
我自己的思路是首先利用sort函数将数组排好序。然后构造四个方向变化的函数,然后一个函数结束后,立即调用后一个函数。在函数中设置每一次的限制条件。
我们将顺序划分为:右,下,左,上,这是四次变化的顺序,然后里面设置四个墙壁的值,即碰壁的时候,输入停止。每一次变化后,壁的值会相应变化。比如:每一次右输出之后,上墙壁都会加一,以后的输出到该墙壁为止。最后,在每个函数的最后设置判定结束的条件,当所有的数输完之后,就不再继续变化。
一开始只能通过24分,6个测试点。
这是因为,数组会发生溢出,二维数组的第一个[]里应该申请足够大的空间,这样就不会导致段错误。
感谢大神的博客: 陌生缘林的博客
解释不太好,而且代码也比较繁琐,大家参考就好,大神可以忽略。自己还会想一想更好的算法,解决这个问题。
#include<iostream>
#include<algorithm>
#include<cmath>
#define M 10000
#define N 100
using namespace std;
int left(int shang,int xia,int zuo,int you,int count,int a[],int b[][N],int n);
int right(int shang,int xia,int zuo,int you,int count,int a[],int b[][N],int n);
int up(int shang,int xia,int zuo,int you,int count,int a[],int b[][N],int n);
int down(int shang,int xia,int zuo,int you,int count,int a[],int b[][N],int n);
bool cmp(int a,int b){
return a>b;
}
int test(int x){
for(int i=(int)sqrt(x);i>=1;i--){
if(x%i==0){
return i;
}
}
}
int right(int shang,int xia,int zuo,int you,int count,int a[],int b[][N],int n){
for(int i=zuo;i<=you;i++){
b[shang][i]=a[count];
count++;
}
shang++;
if(count<n){
down(shang,xia,zuo,you,count,a,b,n);
}
else{
return 0;
}
}
int down(int shang,int xia,int zuo,int you,int count,int a[],int b[][N],int n){
for(int i=shang;i<=xia;i++){
b[i][you]=a[count];
count++;
}
you--;
if(count<n){
left(shang,xia,zuo,you,count,a,b,n);
}
else{
return 0;
}
}
int left(int shang,int xia,int zuo,int you,int count,int a[],int b[][N],int n){
for(int i=you;i>=zuo;i--){
b[xia][i]=a[count];
count++;
}
xia--;
if(count<n){
up(shang,xia,zuo,you,count,a,b,n);
}
else{
return 0;
}
}
int up(int shang,int xia,int zuo,int you,int count,int a[],int b[][N],int n){
for(int i=xia;i>=shang;i--){
b[i][zuo]=a[count];
count++;
}
zuo++;
if(count<n){
right(shang,xia,zuo,you,count,a,b,n);
}
else{
return 0;
}
}
int main(){
int n;
cin>>n;
int a[M];
int b[M][N]={0};
if(n==0){
cout<<endl;
}
else{
for(int i=0;i<n;i++){
cin>>a[i];
}
sort(a,a+n,cmp);
int h=test(n);
int l=n/h;
if(l>h){
int temp=l;
l=h;
h=temp;
}
int shang=0,xia=h-1,zuo=0,you=l-1;
int count=0;
right(shang,xia,zuo,you,count,a,b,n);
for(int i=0;i<h;i++){
cout<<b[i][0];
for(int j=1;j<l;j++){
cout<<" "<<b[i][j];
}
cout<<endl;
}
}
return 0;
}