您的位置:首页 > 其它

螺旋矩阵(队列)

2017-08-09 14:35 295 查看
有如下矩阵,设1点的坐标是(0,0),7点的坐标是(-1,-1),2点坐标是(0,1),编程实现输入坐标值,如(a,b),输出其相应的值



观察该矩阵,知道这个矩阵是按顺时针螺旋向外扩展的,我们可以把它分成一圈一圈的,如下:



现在看看(a,b)会处在第几圈呢?点2(0,1)在第2圈,点18(-1,-2)在第2圈,所以圈数就等于max(abs(a),abs(b)),即取a,b的绝对值中最大的一个。且每一圈的最大的那个数为1,9,25。他们之间有什么规律?



1=1^2  ; 9= 3^2  ;25 =5^2;而1,3,5又和圈数有关,设圈数=c,则他们等于2c+1,所以最大值MaxValue=(2c+1)^2;

最后一步,观察一下一圈中的上
4000
下左右边的值,他们又是如何计算的呢



我们就以第三圈为例,找到第三圈各边的基值,因为他们的坐标(a,b)中必有一个为0,方便计算,因此把他们看作基值

对于上边来说,y是不变的,x在变化,即当y=-2(y=-c)时,23=25+(-2),所以上基值topBase=MaxValue+y,因为上边的递增方向是正方向,所以坐标对应的值value=topBase+x;

对于右边来说,x是不变的,y在变化,即当x=2(x=c)时,11=25-14,所以右基值rightBase=MaxValue-7*x,因为右边的递增方向是正方向,所以坐标对应的值value=rightBase+y;对于下边来说,y是不变的,x在变化,即当y=2(y=c)时,15=25-10,所以下基值bottomBase=MaxValue-5*y,因为下边的增长方向是负方向,所以value=bottomBase-x;

对于左边来说,x是不变的,y在变化,即当x=-2(x==-c)时,19=25-6,所以左基值leftBase=MaxValue+3*x;左边增长方向是负方向,所以value=leftBase-x;

代码:

int max(int a,int b){
return a>b?a:b;
}
int abs(int a){
return a>0?a:-a;
}
int test(int x,int y){
int c=max(abs(x),abs(y));//取x,y绝对值中的最大值;圈数
int maxValue=(2*c+1)*(2*c+1);
//上边
if(y==-c){
return maxValue+y+x;
}
//右边
else if(x==c){
return maxValue-7*x+y);
}
//下边
else if(y==c){
return maxValue-5*y-x);
}
//左边
else{
return maxValue+3*x-y;
}
}
void main(){
test(2,-2);//17;
//打印整个矩阵
//顺时针
int i,j;
for(i=-4;i<4;i++){
for(j=-4;j<4;j++){
printf("%5d",test(j,i));
}
}
//如果想要逆时针的螺旋矩阵,交换i.j的位置即可
for(i=-4;i<4;i++){
for(j=-4;j<4;j++){
printf("%5d",test(i,j));
}
}
}


【扩展】:
打印如下矩阵A:

 1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9

其实思路差不多,顺时针,都是要分成几圈几圈来看,第一圈从1到16,第二圈从17到24,再好好研究一下:
拿最外一圈研究,坐标(a,b),

int m=1, i=0,j;

上边,从1到5,a不变,b变

for(j=0;j<5;j++) A[i][j]=m++;

右边,从6开始到8,a变,b不变,b=4

for(j=i+1;j<4;j++) A[j][4]=m++;

下边,从10到12,a不变,b变,a=4

for(j=n-i-1;j>i;j--)A[n-i-1][j]=m++;

左边,从13到16,a变,b不变,b=i

for(j=n-i-1;j>i;j--)A[j][i]=m++;

现在是5*5的矩阵,所以就有5/2圈,

所以就要循环5/2次

int m =1 ;
for(i=0;i<n/2;i++){
for(j=0;j<n;j++)A[i][j] = m++;
for(j=i+1;j<n-1;j++)A[j][n-i-1]=m++;
for(j=n-i-1;j>i;j--)A[n-i-1][j]=m++;
for(j=n-i-1;j>i;j--)A[j][i]=m++;}
if(n%2==1){
A[n/2][n/2]=n*n
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: