螺旋数组
最直观的方法是模拟这个顺时针转圈的过程
设数组维数为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);
}