2
114 void fillDoubly(int square[20][20], int n){
115
116     int i, j, k=0, l=0, counter=0, test[400]={0}, diff=n/4-1;
117
118     for(i=0;i<n;i++) //first nested for loops for part 1)
119         for(j=0;j<n;j++){
120             counter++;
121             if( i=j || j=(n-1-i) ){
122                 {
123                     square[i][j] = counter;
124                     test[counter-1] = 1;
125                 }
126             }
127         }
128
129     for(i=n-1;i>=0;i--) // for part 2)
130         for(j=n-1;j>=0;j--){
131             if(square[i][j]==0){
132                 while(test[k]!=0){
133                     k++;
134                 }
135                 test[k]=1;
136                 square[i][j]=k+1;
137             }
138         }
139 }

基本的に、次数 4 の魔方陣を生成する必要があります。つまり、行と列は 4 で割り切れます。

提供されたアルゴリズムは

  1. 配列をトラバースし、対角部分集合を埋めます
  2. 配列を後方にトラバースし、残りを埋める

上記のコードで 4x4 配列を作成しましたが、これは 8x8、12x12 などに拡張されますが、対角サブセットを埋めるパート 1) で立ち往生しています(たとえば、8x8 を 4x4 に分割し、代わりにその対角線を取得します)。 ..それを行う方法がわかりません。対角線自体を埋めることができただけです

if( i=j || j=(n-1-i) ){

tldr、上記は対角かどうかを知るために使用する条件です。対角ではなく対角サブセットであるかどうかを知るために条件を変更する方法はありますか?

ありがとう

4

1 に答える 1

0

リンクしたチュートリアルから私が理解していることから、行列を16個の等しい部分行列に分割し、これらの部分行列を横切る対角線を塗りつぶしたいと考えています。したがって、達成したい8x8マトリックスの場合:

 |   0    |    1    |    2    |    3   |  _
 0001 0002 0000 0000 0000 0000 0007 0008  0
 0009 0010 0000 0000 0000 0000 0015 0016  _
 0000 0000 0019 0020 0021 0022 0000 0000  1
 0000 0000 0027 0028 0029 0030 0000 0000  _
 0000 0000 0035 0036 0037 0038 0000 0000  2
 0000 0000 0043 0044 0045 0046 0000 0000  _
 0049 0050 0000 0000 0000 0000 0055 0056  3
 0057 0058 0000 0000 0000 0000 0063 0064  _

ここで、サブマトリックスは 2x2 です。マトリックスが 12x12 の場合、3x3 の 16 個のサブマトリックスに分割されます。

これらの部分行列を対角を見つけるためのインデックスとして使用する場合 (つまり、i==j)、次の式を使用できます。

if( (i/w)==(j/w)  || (j/w)==(3-(i/w)))

どこw = n/4で、これは正方部分行列の次数です (8x8 の場合、これは 2 です)。そのi/wため、現在のマトリックス インデックスが存在するサブマトリックス (0 ~ 3) が示されiます。

于 2012-11-02T12:51:32.393 に答える