第20講 一般種法による魔方陣ソフトの高速化
第4話 仮屋崎さんのエレガントな方法その2



void g1(int n,int y,int x){
  int i;
  for(i=x;i<n;i++){
    if(b[y][i]==-1){
      b[y][i]=cn;
      cn++;
    }
  }
  t++;
  if(t<n){
    g2(n,t,t-1);
  }
}
void g2(int n,int y,int x){
  int i;
  for(i=y;i<n;i++){
    if(b[i][x]==-1){
      b[i][x]=cn;
      cn++;
    }
  }
  if(t<n){
    g1(n,t,t+1);
  }
}

特に解説はいらないと思いますが、

0 1 2 3 4 5 6 7 8 9
0 0 -1 -1 -1 -1 -1 -1 -1 -1 10
1 -1 1 -1 -1 -1 -1 -1 -1 11 -1
2 -1 -1 2 -1 -1 -1 -1 12 -1 -1
3 -1 -1 -1 3 -1 -1 13 -1 -1 -1
4 -1 -1 -1 -1 4 14 -1 -1 -1 -1
5 -1 -1 -1 -1 15 5 -1 -1 -1 -1
6 -1 -1 -1 16 -1 -1 6 -1 -1 -1
7 -1 -1 17 -1 -1 -1 -1 7 -1 -1
8 -1 18 -1 -1 -1 -1 -1 -1 8 -1
9 19 -1 -1 -1 -1 -1 -1 -1 -1 9

セル単位で再帰的呼び出しをしているのではなく、行または列単位で再帰的呼び出しをしています。
こちらの方が、前のものより簡単ですね。

前話で1つ語り落としたことがあります。
g1(n,t,t+1);とg2(n,t,t-1);の色のところです。
(t,t+1)(t,t-1)の意味は、

0 1 2 3 4 5 6 7 8 9
0 0 -1 -1 -1 -1 -1 -1 -1 -1 10
1 -1 1 -1 -1 -1 -1 -1 -1 11 -1
2 -1 -1 2 -1 -1 -1 -1 12 -1 -1
3 -1 -1 -1 3 -1 -1 13 -1 -1 -1
4 -1 -1 -1 -1 4 14 -1 -1 -1 -1
5 -1 -1 -1 -1 15 5 -1 -1 -1 -1
6 -1 -1 -1 16 -1 -1 6 -1 -1 -1
7 -1 -1 17 -1 -1 -1 -1 7 -1 -1
8 -1 18 -1 -1 -1 -1 -1 -1 8 -1
9 19 -1 -1 -1 -1 -1 -1 -1 -1 9

2つの線です。座標(t、t)なら、対角線でした。ですから、(t、t+1)なら1つ右にずれた直線ですし、
(t、t−1)なら1つ左にずれた直線です。



第20講(再講義)第3話へ  第20講(旧講義)第7話へ


VC++講義第1部へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座