マルチスレッド版数独自動生成ソフトC++コードを題材とする超初心者のためのVisual Studio C++講義
第6章 6次魔方陣・8次魔方陣の作成

第4話 対角線部分を交換する


対角線部分を交換して


1 2 3 4 5 6
7 8 9 10 11 12
13 14 15 16 17 18
19 20 21 22 23 24
25 26 27 28 29 30
31 32 33 34 35 36

36 2 3 4 5 31
7 29 9 10 26 12
13 14 22 21 17 18
19 20 16 15 23 24
25 11 27 28 8 30
6 32 33 34 35 1

を実現するコード例
#include<iostream>//インクルードファイルiostreamの読み込み

#include<conio.h>//while(!_kbhit());を使うためのお呪い

#include<string> //文字列変数を使えるようにするために組み込む

#include <iomanip> //setprecisionを使えるように組み込む

#include <cmath>//powなどを使うときに必要

#include <ctime>//time()(←現時刻発生する関数)を使うために必要

using namespace std;//coutを使うときに必要なお呪い

void 魔方陣();//横と縦の2方向を持つ2次元for文体験

const int n = 6;//これからは具体的な数字を使わずにnとする。左の6を8などに変更すれば8次魔方陣に対応する
//n = 6 の一か所だけ具体的な数字を使い、他ではすべて n を使ってください。

int main() {//私は社長だ。

  魔方陣();

  while (!_kbhit());//待機させるための命令

  return(0);//int main()終わるためのお呪い

}

void 魔方陣() {

  int 2次元配列[n][n];

  for (int i = 0; i < n; i++) {

    for (int j = 0; j < n; j++) {

      2次元配列[i][j] = n * i + j + 1;//自然配列を生成して2次元配列に収納する

    }

  }

  for (int i = 0; i < n; i++) {

    for (int j = 0; j < n; j++) {

      //自然配列に体裁を整えて表示する。

      if (2次元配列[i][j] < 10)cout << " ";

      cout << 2次元配列[i][j]<<" ";

    }

    cout << endl;

  }

  cout << endl;

  int 受け皿;//2次元配列[i][j]などのデータを一時保存する

  //対角線部分を交換する

  //a[0][0]とa[n - 1 - i][n - 1 - i]を交換する
  受け皿 = 2次元配列[0][0];
  //2次元配列[n - 1 - i][n - 1 - i]のデータに上書きされる前に2次元配列[0][0]のデータを保存

  2次元配列[0][0] = 2次元配列[n - 1 - i][n - 1 - i];
  //2次元配列[0][0]のデータを2次元配列[n - 1 - i][n - 1 - i]のデータで上書き

  2次元配列[n - 1 - i][n - 1 - i] = 受け皿;
  //2次元配列[n - 1 - i][n - 1 - i]のデータを2次元配列[0][0]の元データで上書き
  //a[0][0]とa[n - 1 - i][n - 1 - i]のデータ交換終了!

  //a[1][1]とa[4][4]を交換する
  受け皿 = 2次元配列[1][1];
  //2次元配列[4][4]のデータに上書きされる前に2次元配列[1][1]のデータを保存

  2次元配列[1][1] = 2次元配列[4][4];
  //2次元配列[1][1]のデータを2次元配列[4][4]のデータで上書き

  2次元配列[4][4] = 受け皿;
  //2次元配列[4][4]のデータを2次元配列[1][1]の元データで上書き
  //a[1][1]とa[4][4]のデータ交換終了!

  //a[2][2]とa[3][3]を交換する
  受け皿 = 2次元配列[2][2];
  //2次元配列[3][3]のデータに上書きされる前に2次元配列[2][2]のデータを保存

  2次元配列[2][2] = 2次元配列[3][3];

  2次元配列[3][3] = 受け皿;
  //2次元配列[3][3]のデータを2次元配列[2][2]の元データで上書き
  //a[2][2]とa[3][3]のデータ交換終了!

  //対角線部分の交換終了



  //逆対角線部分を交換する

  //a[0][n - 1 - i]とa[n - 1 - i][0]を交換する
  受け皿 = 2次元配列[0][n - 1 - i];
  //2次元配列[n - 1 - i][0]のデータに上書きされる前に2次元配列[0][n - 1 - i]のデータを保存

  2次元配列[0][n - 1 - i] = 2次元配列[n - 1 - i][0];
  //2次元配列[0][n - 1 - i]のデータを2次元配列[n - 1 - i][0]のデータで上書き

  2次元配列[n - 1 - i][0] = 受け皿;
  //2次元配列[n - 1 - i][0]のデータを2次元配列[0][n - 1 - i]の元データで上書き
  //a[0][n - 1 - i]とa[n - 1 - i][0]の交換終了!

  //a[1][4]とa[4][1]を交換する
  受け皿 = 2次元配列[1][4];
  //2次元配列[4][1]のデータに上書きされる前に2次元配列[1][4]のデータを保存

  2次元配列[1][4] = 2次元配列[4][1];
  //2次元配列[1][4]のデータを2次元配列[4][1]のデータで上書き

  2次元配列[4][1] = 受け皿;
  //2次元配列[4][1]のデータを2次元配列[1][4]の元データで上書き
  //a[1][4]とa[4][1]の交換終了!

  //a[2][3]とa[3][2]を交換する
  受け皿 = 2次元配列[2][3];
  //2次元配列[3][2]のデータに上書きされる前に2次元配列[2][3]のデータを保存

  2次元配列[2][3] = 2次元配列[3][2];
  //2次元配列[2][3]のデータを2次元配列[3][2]のデータで上書き

  2次元配列[3][2] = 受け皿;
  //2次元配列[3][2]のデータを2次元配列[2][3]の元データで上書き
  //a[2][3]とa[3][2]の交換終了!

  //逆対角線部分の交換終了

  for (int i = 0; i < n; i++) {

    for (int j = 0; j < n; j++) {

      //対角線分を交換した配列に体裁を整えて表示する。

      if (2次元配列[i][j] < 10)cout << " ";

      cout << 2次元配列[i][j] << " ";

    }

    cout << endl;

  }

}

さて、次話への課題です。
  //対角線部分を交換する

  //a[0][0]とa[n - 1 - i][n - 1 - i]を交換する
  受け皿 = 2次元配列[0][0];
  //2次元配列[n - 1 - i][n - 1 - i]のデータに上書きされる前に2次元配列[0][0]のデータを保存

  2次元配列[0][0] = 2次元配列[n - 1 - i][n - 1 - i];
  //2次元配列[0][0]のデータを2次元配列[n - 1 - i][n - 1 - i]のデータで上書き

  2次元配列[n - 1 - i][n - 1 - i] = 受け皿;
  //2次元配列[n - 1 - i][n - 1 - i]のデータを2次元配列[0][0]の元データで上書き
  //a[0][0]とa[n - 1 - i][n - 1 - i]のデータ交換終了!

  //a[1][1]とa[4][4]を交換する
  受け皿 = 2次元配列[1][1];
  //2次元配列[4][4]のデータに上書きされる前に2次元配列[1][1]のデータを保存

  2次元配列[1][1] = 2次元配列[4][4];
  //2次元配列[1][1]のデータを2次元配列[4][4]のデータで上書き

  2次元配列[4][4] = 受け皿;
  //2次元配列[4][4]のデータを2次元配列[1][1]の元データで上書き
  //a[1][1]とa[4][4]のデータ交換終了!

  //a[2][2]とa[3][3]を交換する
  受け皿 = 2次元配列[2][2];
  //2次元配列[3][3]のデータに上書きされる前に2次元配列[2][2]のデータを保存

  2次元配列[2][2] = 2次元配列[3][3];

  2次元配列[3][3] = 受け皿;
  //2次元配列[3][3]のデータを2次元配列[2][2]の元データで上書き
  //a[2][2]とa[3][3]のデータ交換終了!

  //対角線部分の交換終了

の部分をfor文に書き換えてもっとすっきりしたコードに変くしてください。

主対角線: (0,0) (1,1) (2,2) (3,3) (4,4) (5,5)

逆対角線: (0,5) (1,4) (2,3) (3,2) (4,1) (5,0)




第6章第3話へ 第6章第5話へ

本講義トップへ