본문 바로가기

코딩 테스트/BAEKJOON

[Java] 16926 배열돌리기 1

문제

문제
크기가 N×M인 배열이 있을 때, 배열을 돌려보려고 한다. 배열은 다음과 같이 반시계 방향으로 돌려야 한다.

A[1][1] ← A[1][2] ← A[1][3] ← A[1][4] ← A[1][5]
   ↓                                       ↑
A[2][1]   A[2][2] ← A[2][3] ← A[2][4]   A[2][5]
   ↓         ↓                   ↑         ↑
A[3][1]   A[3][2] → A[3][3] → A[3][4]   A[3][5]
   ↓                                       ↑
A[4][1] → A[4][2] → A[4][3] → A[4][4] → A[4][5]
예를 들어, 아래와 같은 배열을 2번 회전시키면 다음과 같이 변하게 된다.

1 2 3 4       2 3 4 8       3 4 8 6
5 6 7 8       1 7 7 6       2 7 8 2
9 8 7 6   →   5 6 8 2   →   1 7 6 3
5 4 3 2       9 5 4 3       5 9 5 4
 <시작>         <회전1>        <회전2>
배열과 정수 R이 주어졌을 때, 배열을 R번 회전시킨 결과를 구해보자.

문제 풀이

우선 배열을 받았을 때 돌려야할 그룹의 수가 몇 개인지가 중요하다.

입력받은 n,m 중 작은 값을 / 2 하면 그룹의 수가 나온다. = Math.min(n, m) / 2

다음으로 temp 배열을 만들 것이 아니라면 배열을 한 칸 돌릴 때 처음 시작 값을 빼놓았다가 돌리는 작업이 끝난 뒤 필요한 위치에 해당 값을 삽입해야한다. 

더욱 자세한 로직은 주석으로 남긴다.

자바 코드

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

public class N16926 {
    private static int n, m, r;
    private static int group;
    private static int[][] arr;
    private static final int[] dr = {0, 1, 0, -1};
    private static final int[] dc = {1, 0, -1, 0};

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");

        n = Integer.parseInt(st.nextToken());
        m = Integer.parseInt(st.nextToken());
        r = Integer.parseInt(st.nextToken());

        arr = new int[n][m];
        
        // 그룹의 수, n과 m중 작은 쪽의 나누기 2 한 값이 그룹의 수가 된다.
        group = Math.min(n,m) / 2;

        for(int i = 0; i < arr.length; i++){
            st = new StringTokenizer(br.readLine(), " ");
            for(int j = 0; j < arr[i].length; j++){
                arr[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        // 회전 수 만큼 실행
        for(int i = 0; i < r; i++)
            rotate();

        // 출력
        for(int[] arrA : arr){
            for(int i : arrA){
                System.out.print(i + " ");
            }
            System.out.println();
        }
    }

    public static void rotate(){
        int x, y, idx;
        // 그룹 수 만큼 실행한다.
        for(int i = 0; i < group; i++){
            // 그룹 시작 인덱스 x, y
            // 1그룹이면 0,0 2그룹이면 1,1 등으로 시작한다.
            x = i;
            y = i;

            // 처음의 인덱스 값을 미리 빼놓는다.
            // 맨 마지막에 i+1, i 인덱스 위치에 삽입해준다.
            int temp = arr[x][y];

            // 방향 초기화
            idx = 0;
            // 4방향을 다 돌때까지 진행한다.
            // dr, dc에 따라서 우,하,좌,상 방향으로 탐색한다.
            while(idx < 4){
                // 현재 위치에서 우,하,좌,상 방향의 인덱스 위치를 얻는다.
                int nx = x + dr[idx];
                int ny = y + dc[idx];

                // 해당 인덱스 위치가 그룹의 범위를 벗어나지 않는 경우에 현 (x,y)에 (nx,ny)값을 넣어준다.
                // 예를 들자면 맨처음 0,0에서 시작하여 오른쪽 값(0,1 .... 0,m)을 확인하면서 넣어줄 것이다.
                // 그러다가 오른쪽 범위를 벗어나면 (0, m+1) 그때부터는 idx를 1 올려주어 아랫쪽으로 이동하는 것. (1, m)
                if(nx < n - i && ny < m - i && nx >= i && ny >= i){
                    arr[x][y] = arr[nx][ny];
                    x = nx;
                    y = ny;
                }else{
                    idx++;
                }
            }

            // 마지막으로 처음 빼놓았던 i,i 인덱스 위치의 값을 삽입한다.
            arr[i + 1][i] = temp;
        }
    }
}

 

'코딩 테스트 > BAEKJOON' 카테고리의 다른 글

[Java] 15558 점프 게임  (0) 2024.05.14
[Java] 16927 배열 돌리기 2  (0) 2024.05.09
[Java] 2290 LCD Test  (0) 2024.05.09
[Java] 16931 겉넓이 구하기  (0) 2024.05.08
[Java] 16967 배열 복원하기  (0) 2024.05.07