スパイラルマトリックス(キュー)


次の行列があります.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;

最後のステップで、円の上部、下部、左側、右側の値を観察します。どのように計算しますか?


3番目の円を例として取り上げて、3番目の円の各辺の基本値を見つけます。これらの座標(a、b)の1つは計算に便利な0でなければならないため、これらを基本値と見なします。

上記の場合、yは変更されず、xは変更されます。つまり、y = -2(y = -c)、23 = 25 +(-2)の場合、上限ベース値topBase = MaxValue + y、の増加方向は正の方向であるため、座標値に対応する値= topBase + x;

右側の場合、xは変更されず、yは変更されます。つまり、x = 2(x = c)、11 = 25-14の場合、右側の方向が増加するため、右側のベース値rightBase = MaxValue-7 * xになります。これは正の方向であるため、座標値= 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で、2番目の円は17から24で、注意深く調べます。

研究する最も外側の円、座標(a、b)、

int m = 1、i = 0、j;

上記では、1から5まで、aは変化せず、bは変化
します(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 = ni-1; j> i; j-)A [ni-1] [j] = m ++;

左側では、13から16まで、aは変化し、bは変化しません、b = i

for(j = ni-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
}


おすすめ

転載: blog.csdn.net/sinat_35803474/article/details/76975256