螺旋数组


螺旋数组

最直观的方法是模拟这个顺时针转圈的过程

设数组维数为m

假设需要转m圈才可以覆盖整个shuzu

第一圈的元素个数为4*dim-4=4*(dim-1)

第二圈的元素个数为4*(dim-3)

即dim*dim=4*(dim-1)+4*(dim-3)+...4*(dim-(2*m-1))

即4*(m*dim-m*m)=dim*dim

(dim-2m)^2=0

m=dim/2

需要转的圈数即为数组维度的一半


当dim为偶数时

m=dim/2

当m为奇数时,m=dim/2+1

因此m=dim/2+dim%2


转圈过程为先行号不变,列号增加

然后列号不变,行号增加

行号不变,列号减小

列号不变,行号减少

这样便走完一圈

直至走满dim/2圈





#include<iostream>
#include<iomanip>
using namespace std;

void spiral_array(int dim){
	//round为需要转的圈数
	//the circle to be looped
	int i,j;
	int num=1;
	int** A=new int*[dim];
	for(int i=0;i<dim;i++){
		A[i]=new int[dim];
	}
	for(int round=0;round<dim/2+dim%2;round++){
		//change column index
		for(j=round;j<dim-round;j++ )
			A[round][j]=num++;	
		//change row index
		for(i=round+1;i<dim-round;i++)
			A[i][dim-round-1]=num++;
		//change column index
		for(j=dim-round-2;j>=round;j--)
			A[dim-round-1][j]=num++;
		//change row index
		for(i=dim-round-2;i>=round+1;i--)
			A[i][round]=num++;
	}

	for(int i=0;i<dim;i++){
		for(int j=0;j<dim;j++)
			cout<<setw(4)<<A[i][j]<<" ";
		cout<<endl;
	}
	for(int i=0;i<dim;i++)
		delete[]A[i];
	delete[] A;


}
int main(){
    
	while(true){
		int dim;
		cout<<"please enter the dimension of the array"<<endl;
		cout<<"enter 0 to exit"<<endl;
		cin>>dim;
		if(dim==0)
			break;
		spiral_array(dim);

	}

}



方法二:不用存储空间的方案


1     2     3

8 9      4

7    6      5


模拟人画这个圈的时候,每一个小圈的左上角的数字很容易可以求出。

round为对应走这个螺旋数组的第几圈,dim为数组维度

第一圈(索引为0)的数字个数为4*(dim-1),第二圈数字为4*(dim-3)

第m+1圈(索引为m)的数字个数为4*(dim-2*(m-1))

所以第m+1圈(索引为m)左上角数字为  1+4*(dim-1)+4*(dim-3)+..4*(dim-2(m-1))=1+4*round*(dim-round)


每圈顶点的数字相应地从左上角顶点数字依次递增(顺时针方向)dim-2*m-1(比如0圈顶点数字相应地增加dim-1)

所以只要获取输出位置所在的圈数及处在该圈的哪条边上,即可求出所需的值。

判断该点处于下图中的哪条边上(是1,2,3还是4),因为左上角顶点的数字很容易求出,剩下点的坐标也不难获取了




#include<iostream>
#include<iomanip>
using namespace std;


void spiral(int dim){
	int row;
	int column;
	int round;
	for(int i=0;i<dim;i++){
		for(int j=0;j<dim;j++){
			
			//row start from top left,the ith round
			//row is the current row's symmetrical row,which maybe the round number
			row=dim-i-1;
			round is the current column's symmetrical column,which maybe the
			//round number
			round=dim-j-1;
			if(j>=i&&j<dim-i){
				cout<<setw(4)<<1+4*i*(dim-i)+j-i<<" ";

			}
			//row start from bottom right
			else if(j>=row&&j<dim-row){
				cout<<setw(4)<<1+4*row*(dim-row)+2*(dim-2*row-1)+(dim-row-1-j)<<" ";
			}
			//column start from bottom left
			else if(i>j&&i<dim-j-1){
				cout<<setw(4)<<1+4*j*(dim-j)+3*(dim-2*j-1)+(dim-j-1-i)<<" ";
			}
			//column start from top right
			else if(i>round&&i<dim-round-1){
				cout<<setw(4)<<1+4*round*(dim-round)+(dim-2*round-1)+(i-round)<<" ";
			}
		}
		cout<<endl;
	}
}
int main(){
	spiral(7);
	

}




  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值