第19講 魔方陣汎用的生成プログラムVer.2

第2話 対角線優先番号付けはいかに可能か

10 11
12 13
14 15


4
10 11
12 13 14
15 16 17 18
19 20 21
4 22 23 24

どのようにしたら、上のような番号付けは可能でしょうか。
私が、サイト上にアップしていたVBA版はかなり複雑です。
ですが、VC++入門講義の読者の仮屋崎さんから天才的なアイディアがそれられました。
今回それを紹介しましょう。



手順は
public static void z()
内に配列
int[][] a=new int[20][20];
用意してから
① 各座標から番号へ
② 番号から各座標へ
という2段階を踏みます。
①は、a[i][j]に番号を割り振るという意味です。
そして、②で逆対応をさせて、番号に座標を割り振ります。
①はここまでついてきた皆さんでしたら、簡単だと思いますが、
逆対応の②は、かなり難しいですよ。
ですが、コードは数行です。

皆さん、コード
class x{
  public static int[] x=new int[100];
  public static int[] y=new int[100];
  public static int[][] m=new int[20][20];
  public static int n,cn;
  public static void main(String args[]) throws IOException {
    BufferedReader a = new BufferedReader(new InputStreamReader(System.in));
    System.out.println("何次魔方陣を生成させますか。");
    System.out.print ("n=");
    n=Integer.parseInt(a.readLine());
    cn=0;
    z();
    f(0);
    System.out.println();
    System.out.println(n+"次魔方陣が"+cn+"個できました。");
  }
  public static void z(){
    int i;
    for(i=0;i<n*n;i++){
      x[i]=i%n;
      y[i]=i/n;
    }
  }

  public static void f(int g){
    int i,j,k,h,w;
    for(i=1;i<n*n+1;i++){
      h=1;
      m[y[g]][x[g]]=i;
      for(j=0;j<g;j++){
        if(m[y[g]][x[g]]==m[y[j]][x[j]]){
          h=0;
        }
      }
      if(h==1){
        if(x[g]==n-1){
          w=0;
          for(j=0;j<n;j++){
            w+=m[y[g]][j];
          }
          if(w!=n*(n*n+1)/2)h=0;
        }
      }
      if(h==1){
        if(y[g]==n-1){
          w=0;
          for(j=0;j<n;j++){
            w+=m[j][x[g]];
          }
          if(w!=n*(n*n+1)/2)h=0;
        }
      }
      if(h==1){
        if(y[g]==n-1 && x[g]==0){
          w=0;
          for(j=0;j<n;j++){
            w+=m[j][n-1-j];
          }
          if(w!=n*(n*n+1)/2)h=0;
        }
      }
      if(h==1){
        if(y[g]==n-1 && x[g]==n-1){
          w=0;
          for(j=0;j<n;j++){
            w+=m[j][j];
          }
          if(w!=n*(n*n+1)/2)h=0;
        }
      }
      if(h==1){
        if(g+1<n*n){
          f(g+1);
          //if(cn>20)return;
        }
        else{
          cn++;
          for(j=0;j<n;j++){
            for(k=0;k<n;k++){
              if(m[j][k]<10){
                System.out.print(" "+m[j][k]+" ");
              }
              else{
                System.out.print(m[j][k]+" ");
              }
            }
            System.out.println();
          }
          System.out.println();
          //if(cn>20)return;
        }
      }
    }
  }
}
ピンクの部分改良して実現してください。





第1話へ 第3話へ

戻る

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

初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)
初心者のための VC++による C言語 入門 C++ 入門 基礎から応用まで第1部
初心者のための VC++による C言語 入門 C++ 入門 基礎から応用まで第2部
初心者のための VC++による C言語 入門 C++ 入門 基礎から応用まで第3部