Advertisement
vov44k

Untitled

Jan 27th, 2022
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 8.08 KB | None | 0 0
  1. // magicSquareOfOddOrder(int n);       метод для n нечетной размерности (3, 7, 9, и тд)
  2. // magicSquareOfEvenOddOrder(int n);   метод для n четно-нечетной размерности (n кратно 2 но не крастно 4)
  3. // magicSquareOfEvenOddOrder(int n);   метод для n четн-четной размерности (n кратно и 2 и 4);
  4. // magicSquare(int n);                 общий метод, который определяет кратность n и вызывает соотв. метод
  5.  
  6. // Вспомогательные методы
  7. // standardMatrixFillingAscending(n); заполняет матрицу от 1 по возростанию
  8. // standardMatrixFillingDescending(n); заполняет матрицу от n*n по убыванию
  9.  
  10. import java.util.*;
  11.  
  12.  
  13.  
  14. public class Main {
  15.     public static void main(String[] args) {
  16.         Scanner in = new Scanner(System.in);
  17.         int n = in.nextInt();
  18.         int[][] ans = magicSquare(n);
  19.         for (int i = 0; i < n; i++) {
  20.             for (int j = 0; j < n; j++) {
  21.                 System.out.print(ans[i][j] + " ");
  22.             }
  23.             System.out.println();
  24.         }
  25.     }
  26.  
  27.     public static int[][] magicSquare(int n) {
  28.         if (n % 2 != 0) return magicSquareOfOddOrder(n);             // метод для n нечетной размерности (3, 7, 9, и тд)
  29.         else if (n % 4 != 0)
  30.             return magicSquareOfEvenOddOrder(n);   // метод для n четно-нечетной размерности (n кратно 2 но не кратно 4)
  31.         return evenMatrixSquare(n);                        // метод для n четн-четной размерности (n кратно и 2 и 4);
  32.     }
  33.  
  34.     private static int[][] magicSquareOfOddOrder(int n) {
  35.         // "Сиамский метод" - один из самых просты для восприятия
  36.         // https://ru.xcv.wiki/wiki/Siamese_method
  37.         // Оставлю без комментариев (gif по ссылке наглядно показывает как он работает)
  38.         // код не сложный
  39.         int[][] matrix = new int[n][n];
  40.         for (int i = 0; i < n; i++) {
  41.             Arrays.fill(matrix[i], 0);
  42.         }
  43.         int count = 1, y = 0, x = matrix.length / 2;
  44.         do {
  45.             matrix[y][x] = count;
  46.  
  47.             count++;
  48.             if (((y == 0) && (x >= n - 1)) && (matrix[n - 1][0] != 0)) {
  49.                 y++;
  50.             } else {
  51.                 y--;
  52.                 if (y < 0) {
  53.                     y = n - 1;
  54.                 }
  55.                 x++;
  56.                 if (x == n) {
  57.                     x = 0;
  58.                 }
  59.                 if (matrix[y][x] != 0) {
  60.                     y += 2;
  61.                     x--;
  62.                 }
  63.             }
  64.  
  65.         } while (count != n * n + 1);
  66.         return matrix;
  67.     }
  68.  
  69.     private static int[][] magicSquareOfEvenOddOrder(int n) {
  70.         // Метод "анонима" спасибо человеку, который его придумал
  71.         // Вот ссылка на подробное описание метода http://www.klassikpoez.narod.ru/mojmetod.htm
  72.         // Оставлю этот код без комментариев уж очень он большой
  73.         // Надеюсь прочитав описание метода сможете понять(или нет?)
  74.         int half = n / 2;
  75.  
  76.         int[][] matrix = new int[n][n];
  77.         int[][] tempMatrix;
  78.         tempMatrix = magicSquareOfOddOrder(half);
  79.  
  80.         // 1/4 матрицы
  81.         for (int i = 0; i < half; i++) {
  82.             System.arraycopy(tempMatrix[i], 0, matrix[i], 0, half);
  83.         }
  84.         // 2/4 матрицы
  85.         for (int i = 0; i < half; i++) {
  86.             for (int j = half; j < n; j++) {
  87.                 int x = j - half;
  88.                 matrix[i][j] = (tempMatrix[i][x] + 2 * half * half);
  89.             }
  90.         }
  91.         // 3/4 матрицы
  92.         for (int i = half; i < n; i++) {
  93.             for (int j = 0; j < half; j++) {
  94.                 int x = i - half;
  95.  
  96.                 matrix[i][j] = (tempMatrix[x][j] + 3 * half * half);
  97.             }
  98.         }
  99.         // 4/4 матрицы
  100.         for (int i = half; i < n; i++) {
  101.             for (int j = half; j < n; j++) {
  102.                 int x = i - half, y = j - half;
  103.                 matrix[i][j] = (tempMatrix[x][y] + half * half);
  104.             }
  105.         }
  106.         int move = 0;
  107.         for (int i = 6; i < n; i++) {
  108.             if ((i % 4 != 0) && (i % 2 == 0)) move++;
  109.         }
  110.         for (int j = matrix.length / 2 - move; j <= matrix.length / 2 + move - 1; j++) {
  111.             for (int i = 0; i < tempMatrix.length; i++) {
  112.  
  113.                 int key = matrix[i][j];
  114.                 matrix[i][j] = matrix[half + i][j];
  115.                 matrix[half + i][j] = key;
  116.             }
  117.         }
  118.         for (int j = 0; j <= 1; j++) {
  119.             if (j == 0) {
  120.                 int key = matrix[0][0];
  121.                 matrix[0][0] = matrix[half][0];
  122.                 matrix[half][0] = key;
  123.             }
  124.             if (j == 1) {
  125.                 int key = matrix[half - 1][0];
  126.                 matrix[half - 1][0] = matrix[n - 1][0];
  127.                 matrix[n - 1][0] = key;
  128.             }
  129.         }
  130.         for (int j = half + 1; j < n - 1; j++) {
  131.             for (int i = 1; i < half - 1; i++) {
  132.                 int key = matrix[i][1];
  133.                 matrix[i][1] = matrix[half + i][1];
  134.                 matrix[half + i][1] = key;
  135.             }
  136.         }
  137.         return matrix;
  138.     }
  139.  
  140.     private static int[][] evenMatrixSquare(int n) {
  141.         // Метод Раус-Болла хорошое описание нашел тут:
  142.         // https://rep.bntu.by/bitstream/handle/data/62327/Magicheskie_kvadraty.pdf?sequence=1&isAllowed=y
  143.         // Страница 8, 9
  144.         int[][] matrix = standardMatrixFillingAscending(n);
  145.         int[][] tempMatrix = standardMatrixFillingDescending(n);
  146.  
  147.         int size = 4;    // Размерность каждого квадрата (4х4 тафтология)
  148.         // можно заменить простой цифрой
  149.         int x = 0;       // x, y - движение по кадратам (посмотрите как изменяются в ходе программы)
  150.         int y = 0;
  151.         for (int i = 0; i < (n * n / 16); i++) {                // Смотрим сколько квадратов 4х4 помещается в матрице nxn
  152.             if (x == (int) Math.sqrt(n * n / 16)) {              // x, y переменные для движения по квадратам 4х4
  153.                 // х проходит по первому ряду квадратов, достигая последнего
  154.                 // обнуляется, а y увеличивается
  155.                 x = 0;
  156.                 y++;
  157.             }
  158.             // x и y должны лишь обеспечивать проход по квадратам
  159.             for (int j = 0; j < 4; j++) {
  160.                 matrix[size * y + j][size * x + j] = tempMatrix[size * y + j][size * x + j];  // главная диагональ квадратов 4х4
  161.                 int i1 = size * x + size - 1 - j;
  162.                 matrix[size * y + j][i1] = tempMatrix[size * y + j][i1]; // побочная диагональ
  163.             }
  164.             x++;
  165.         }
  166.         return matrix;
  167.     }
  168.  
  169.     public static int[][] standardMatrixFillingAscending(int n) {
  170.         int[][] matrix = new int[n][n];
  171.         int k = 1;
  172.         for (int i = 0; i < n; i++) {
  173.             for (int j = 0; j < n; j++) {
  174.                 matrix[i][j] = k++;
  175.             }
  176.         }
  177.         return matrix;
  178.     }
  179.  
  180.     public static int[][] standardMatrixFillingDescending(int n) {
  181.         int[][] matrix = new int[n][n];
  182.         int k = n*n;
  183.         for (int i = 0; i < n; i++) {
  184.             for (int j = 0; j < n; j++) {
  185.                 matrix[i][j] = k--;
  186.             }
  187.         }
  188.         return matrix;
  189.     }
  190. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement