본문 바로가기
백준/1 - 5000

[백준] 1307번 : 마방진(JAVA)

by lms0806 2021. 9. 26.
728x90
반응형

https://www.acmicpc.net/problem/1307

 

1307번: 마방진

마방진이란 N*N의 격자의 각 칸에 1부터 N*N까지의 정수를 정확히 하나씩 채웠을 때, 모든 가로줄, 세로줄, 대각선의 합이 같은 배치를 말한다. 예를 들면, 다음은 3*3 마방진 중 하나이다. 가로줄,

www.acmicpc.net

풀이

※ 출처 : https://destiny738.tistory.com/244?category=48883 

 

홀수 마방진

홀수 마방진은 마방진을 만드는 것중에서 가장 간단한 형태이다. 위에서 파란원이 만들려고 하는 마방진이다.(크기 3짜리 3*3 마방진을 만든다.) 다음과 같은 과정을 따르며 마방진을 완성해간다

destiny738.tistory.com

여기 사이트에 적혀져 있는 분의 내용을 보고 소스코드를 작성하시면 됩니다.

 

소스코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		int n = Integer.parseInt(br.readLine());
		
		int[][] arr = n % 2 == 1 ? odd(n) : n % 4 == 0 ? fourmul(n) : even(n);
		
		StringBuilder sb = new StringBuilder();
		for(int i = 0; i < n; i++) {
			for(int j = 0; j < n; j++) {
				sb.append(arr[i][j] + " ");
			}
			sb.append("\n");
		}
		System.out.print(sb);
	}
	
	public static int[][] odd(int n){
		int[][] num = new int[n][n];
		int x = 0, y = num.length / 2;
		for(int i = 1; i <= n * n; i++) {
			num[x][y] = i;
			if(i % n == 0) {
				x++;
			}
			else {
				x--;
				y++;
				if(x < 0) {
					x = n - 1;
				}
				if(y > n - 1) {
					y = 0;
				}
			}
		}
		return num;
	}
	
	public static int[][] even(int n){
		int[][] num = new int[n][n];
		
		int[][] arr = odd(n / 2);
		
		for(int i = 0; i < n / 2; i++) {
			for(int j = 0; j < n / 2; j++) {
				if(j < (n / 4)) {
					num[i][j] = 3;
				}
			}
		}
		num[n / 4][0] = 0;
		num[n / 4][n / 4] = 3;
		
		for(int i = n / 2; i < n; i++) {
			for(int j = 0; j < n / 2; j++) {
				if(num[i - n / 2][j] == 0) {
					num[i][j] = 3;
				}
			}
		}
		
		for(int i = 0; i < n / 2; i++) {
			for(int j = n / 2; j < n; j++) {
				num[i][j] = n - (n / 4 - 1) - 1 < j ? 1 : 2;
			}
		}
		
		for(int i = n / 2; i < n; i++) {
			for(int j = n / 2; j < n; j++) {
				num[i][j] = num[i - n / 2][j] == 1 ? 2 : 1;
			}
		}
		
		for(int i = 0; i < n; i++) {
			for(int j = 0; j < n; j++) {
				num[i][j] *= (n * n / 4);
			}
		}
		
		int x = 0, y = 0;
		for(int i = 0; i < n; i++) {
			for(int j = 0; j < n; j++) {
				num[i][j] += arr[x][y];
				y++;
				if(y >= n / 2) {
					y = 0;
				}
			}
			x++;
			if(x >= n / 2) {
				x = 0;
			}
		}
		
		return num;
	}
	
	public static int[][] fourmul(int n){
		int[][] num = new int[n][n];
		
		int count = 1;
		for(int i = 0; i < n; i++) {
			for(int j = 0; j < n; j++) {
				num[i][j] = count++;
			}
		}
		
		int temp1 = 25 * n / 100, temp2 = 50 * n / 100;
		for(int i = 0; i < temp1; i++) {
			for(int j = temp1; j < temp1 + temp2; j++) {
				swap(num, i, j, n);
			}
		}
		
		return num;
	}
	
	public static void swap(int[][] num, int temp1, int temp2, int size) {
		int temp = num[temp1][temp2];
		
		num[temp1][temp2] = num[size - 1 - temp1][size - 1 - temp2];
		num[size - 1 - temp1][size - 1 - temp2] = temp;
		
		temp = num[temp2][temp1];
		num[temp2][temp1] = num[size - 1 - temp2][size - 1 - temp1];
		num[size - 1 - temp2][size - 1 - temp1] = temp;
	}
}
728x90
반응형

댓글