[SWEA] D2 - 1961번 | 숫자 배열 회전

EllievV·2024년 11월 15일

🐊 CodingTest

목록 보기
17/18

🔍 문제 보러 가기

N x N 행렬이 주어질 때,
시계 방향으로 90도, 180도, 270도 회전한 모양을 출력하라.

내 코드

package D2;

//SWEA D2 1961번 "숫자 배열 회전" 문제 풀이

import java.util.*;

public class N1961_a {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		
		int T = scanner.nextInt();
		
		StringBuilder result = new StringBuilder();
		
		for (int t = 1; t <= T; t++) {
			int N = scanner.nextInt();
			
			int[] arr = new int[N * N];
			int idx = 0;
			
			for (int i = 0; i < N; i++) {
				for (int j = 0; j < N; j++) {
					arr[idx++] = scanner.nextInt();
				}
			}
			result.append(String.format("#%d\n%s", t, solution(arr, N)));
		}
		
		System.out.print(result);
		scanner.close();
	}
	
	public static String solution(int[] arr, int N) {
		
		// 90도 회전 
		int[][] arr_90 = new int[N][N];
		int idx = 0;
		for (int i = N - 1; i >= 0; i--) {
			for (int j = 0; j < N; j++) {
				arr_90[j][i] = arr[idx++];
			}
		}
		
		// 180도 회전
		int[][] arr_180 = new int[N][N];
		idx = 0;
		for (int i = N - 1; i >= 0; i--) {
			for (int j = N - 1; j >= 0; j--) {
				arr_180[i][j] = arr[idx++];
			}
		}
		
		// 270도 회전
		int[][] arr_270 = new int[N][N];
		idx = 0; 
		for (int j = 0; j < N; j++) {
			for (int i = N - 1; i >= 0; i--) {
				arr_270[i][j] = arr[idx++];
			}
		}
				
		return arrayToString(arr_90, arr_180, arr_270, N);
	}
	
	public static String arrayToString(int[][] arr_1, int[][] arr_2, int[][] arr_3, int N) {
		StringBuilder result = new StringBuilder();
		
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				result.append(arr_1[i][j]);
			}
			result.append(" ");
			for (int j = 0; j < N; j++) {
				result.append(arr_2[i][j]);
			}
			result.append(" ");
			for (int j = 0; j < N; j++) {
				result.append(arr_3[i][j]);
			}
			result.append("\n");
		}
		return result.toString();		
	}
}

접근 방법

  1. 가로 탐색, 세로 탐색, 격자 탐색 순으로 진행한다.

  2. 각 행(열, 격자)에서 각 숫자가 1번씩 나오는지를 확인하기 위해서 배열을 선언해서 사용한다.

  3. 각 행(열, 격자)을 순회하면서 숫자에 해당하는 인덱스의 배열 값에 1 증가시킨다.

  4. 해당 배열을 순회하면서 비어있거나 1 초과로 들어있는지 확인한다. 해당 경우는 틀린 스도쿠이므로 0을 리턴한다.

  5. 세로 탐색, 격자 탐색인 경우 1차원 배열로 추출해 탐색을 진행한다.

접근 방식

회전 방향에 따라 숫자들이 순서대로 들어가기 때문에 입력받은 2차원 배열을 1차원 배열로 만들어서 사용했다.

90도 회전, 180도 회전, 270도 회전에 맞게 이중 반복문 index 순서를 정하고 알맞은 위치에 값을 넣는다.

개선 코드

package D2;

//SWEA D2 1961번 "숫자 배열 회전" 문제 풀이 개선

import java.util.*;

public class N1961_b {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		
		int T = scanner.nextInt();
		
		StringBuilder result = new StringBuilder();
		
		for (int t = 1; t <= T; t++) {
			int N = scanner.nextInt();
			
			int[][] arr = new int[N][N];

            for (int i = 0; i < N; i++) {
                for (int j = 0; j < N; j++) {
                    arr[i][j] = scanner.nextInt();
                }
            }
			result.append(String.format("#%d\n%s", t, solution(arr, N)));
		}
		
		System.out.print(result);
		scanner.close();
	}
	
	// 회전 처리 함수 
	public static int[][] rotate90(int[][] arr, int N) {
		int[][] rotated = new int[N][N];
		
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				rotated[j][N - 1 - i] = arr[i][j];
			}
		}
		
		return rotated;
	}
	
	public static String solution(int[][] arr, int N) {
		
		// 90도, 180도, 270도 회전 처리
        int[][] arr_90 = rotate90(arr, N);
        int[][] arr_180 = rotate90(arr_90, N);
        int[][] arr_270 = rotate90(arr_180, N);

        return arrayToString(arr_90, arr_180, arr_270, N);
	}
	
	public static String arrayToString(int[][] arr_1, int[][] arr_2, int[][] arr_3, int N) {
		StringBuilder result = new StringBuilder();
		
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				result.append(arr_1[i][j]);
			}
			result.append(" ");
			for (int j = 0; j < N; j++) {
				result.append(arr_2[i][j]);
			}
			result.append(" ");
			for (int j = 0; j < N; j++) {
				result.append(arr_3[i][j]);
			}
			result.append("\n");
		}
		return result.toString();		
	}
}
  1. 회전 시키는 코드를 간결화

    기존 코드는 90도, 180도, 270도 회전에 대해 각각 이중 반복문을 세 번 선언해 사용했다.

    하지만 180도와 270도 회전은 90도 회전된 배열을 한 번 더 회전시키는 방식이므로, 90도 회전 메서드를 별도로 분리하여 이를 재사용하는 방식으로 코드를 간결화하고자 했다.

    예를 들어, 다음과 같은 2차원 배열이 주어졌다고 가정해보자.

    123
    456
    789

    이 배열을 90도 회전시키면 다음과 같은 결과가 나온다.

    741
    852
    963

    이때, 2차원 배열 arr를 90도 회전시키기 위해서는 각 원소를 알맞은 위치에 넣어야 한다.

    예시에서 보면, 인덱스 i (행을 결정)는 0부터 2까지 범위를 가지며, j (열을 결정)는 2부터 0까지 감소하는 범위를 가진다.

    즉, j가 2일 때, i는 0, 1, 2로 변하면서 순서대로 값을 배열에 넣어야 한다.
    이를 반복문으로 나타내면, 반복문 내에서 arr[][] 배열의 값을 arr[j][i] 위치에 넣어야 하기 때문에 j가 첫 번째, i가 두 번째 인덱스로 오는 방식으로 작성된다.

    이러한 방식으로 90도 회전 메서드를 구현하고, 이를 재사용하여 180도와 270도 회전 결과를 얻을 수 있다.

  1. 2D 배열로 처리

    초기 arr 배열을 2D 배열로 바로 처리해 arr를 1D 배열로 변환할 필요가 없게 했다.

0개의 댓글