1050--螺旋矩阵

许久没刷题了,赶紧趁着晚上心情不错来一道。

这次思路出来得挺快的,也是很幸运了。

问题在于我逻辑还是有点乱,这题很考察循环边界,所以很需要头脑清晰,显然我不大清晰。一大通魔改【包括不限于删除多余变量。。。】后,总算看着清晰了一些,放上来纪念下。

#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
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值