许久没刷题了,赶紧趁着晚上心情不错来一道。
这次思路出来得挺快的,也是很幸运了。
问题在于我逻辑还是有点乱,这题很考察循环边界,所以很需要头脑清晰,显然我不大清晰。一大通魔改【包括不限于删除多余变量。。。】后,总算看着清晰了一些,放上来纪念下。
#include <stdio.h>
#include<math.h>
void shellpaixu(int a[],int N);
void printarr(int a[],int N);
int max(int m,int n){
if(m>n){
return m;
//TODO
}
return n;
}
int min(int m,int n){
if(m<n){
return m;
//TODO
}
return n;
}
int main(){
int N;
scanf("%d",&N);
int a[N];
for(int i=0;i<N;i++){//输入数组
scanf("%d",&a[i]);
//TODO
}
shellpaixu(a,N); //希尔排序
int dm,dn;
for(int i=(int)sqrt(N);i<=N;i++){//找到题目要求的合适的m与n
if(i*(N/i)==N){
dm=max(i,N/i);
dn=N/dm;
break;
//TODO
}
//TODO
}
int b[dm][dn];
int index=0;//记录a的下标
int round=min(dm,dn)/2+min(dm,dn)%2;//螺旋圈数
for(int i=0;i<round;i++){
int j,k,x,y;
for(j=i;j<dn-i&&index<N;j++){ //----
b[i][j]=a[index];
index++;
//TODO
}
for(k=i+1;k<dm-i&&index<N;k++){ //|
b[k][dn-i-1]=a[index];
index++;
//TODO
}
for(x=dn-1-i-1;x>=i&&index<N;x--){ //----
b[dm-i-1][x]=a[index];
index++;
//TODO
}
for(y=dm-1-i-1;y>=i+1&&index<N;y--){ //|
b[y][i]=a[index];
index++;
//TODO
}
//TODO
}
for(int i=0;i<dm;i++){ //打印输出数组
for(int j=0;j<dn;j++){
printf("%d",b[i][j]);
if(j!=dn-1){
printf(" ");
//TODO
}
//TODO
}
if(i!=dm-1){
printf("\n");
//TODO
}
//TODO
}
return 0;
}
void printarr(int a[],int N){
for(int i=0;i<N;i++){
printf("%d ",a[i]);
//TODO
}
printf("\n");
}
void shellpaixu(int a[],int N){
int inc,i,j;
int Sedgewick[] = {260609,146305,64769,36289,16001,8929,
3905,2161,929, 505,209, 109, 41,
19, 5, 1, 0};//或者gn+1=3gn+1
int si;
for(si=0;Sedgewick[si]>=N;si++);//用来得到一个初始的恰当的inc。
for(int inc=Sedgewick[si];inc>0;inc=Sedgewick[++si]){
for(i=inc;i<N;i++){
int t=a[i];
for(j=i;j>=inc&&t>a[j-inc];j-=inc){
a[j]=a[j-inc];
//TODO
}
a[j]=t;
//TODO
}
//TODO
}
}