티스토리 뷰

728x90
:D 문제

문제

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

예를 들어, 아래와 같은 배열을 2번 회전시키면 다음과 같이 변하게 된다.

배열과 정수 R이 주어졌을 때, 배열을 R번 회전시킨 결과를 구해보자.

입력

첫째 줄에 배열의 크기 N, M과 수행해야 하는 회전의 수 R이 주어진다.

둘째 줄부터 N개의 줄에 배열 A의 원소 Aij가 주어진다.

출력

입력으로 주어진 배열을 R번 회전시킨 결과를 출력한다.

제한

  • 2 ≤ N, M ≤ 300
  • 1 ≤ R ≤ 1,000
  • min(N, M) mod 2 = 0
  • 1 ≤ Aij ≤ 108
 

Baekjoon

 

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]

www.acmicpc.net

 
:D 풀이 방법

아래 배열(왼쪽)과 같이 4x4인 배열이 주어질 때, 해당 배열을 반시계 방향으로 한번 회전한 모습(오른쪽)이다.  

해당 과정을 구현하기 위해 먼저, 탐색할 배열의 첫 번째 값을 first라는 변수에 저장해두었다.

그리고 오른쪽 -> 위 -> 왼쪽 -> 아래 순으로 2차원 배열을 탐색하여, 위치를 변경해주었다.

아래 이미지의 과정을 탐색 라인별로 반복하였다.

 

:D 작성 코드

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

public class Solution16926 {

    static int N, M, R, count;
    // 우 -> 상 -> 좌 -> 하 순으로 탐색
    static int[] dx = {0, 1, 0, -1};
    static int[] dy = {1, 0, -1, 0};

    static int[][] array;

    public static void main(String[] args) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        String input = br.readLine();
        StringTokenizer tokenizer = new StringTokenizer(input, " ");
        N = Integer.parseInt(tokenizer.nextToken());
        M = Integer.parseInt(tokenizer.nextToken());
        R = Integer.parseInt(tokenizer.nextToken());
        count = Math.min(N, M) / 2;
        array = new int[N][M];

        // input
        for (int i = 0; i < N; i++) {
            input = br.readLine();
            tokenizer = new StringTokenizer(input, " ");
            for (int j = 0; j < M; j++) {
                array[i][j] = Integer.parseInt(tokenizer.nextToken());
            }
        }

        // rotate array
        int rotateCount = 0;
        while (rotateCount < R) {
            rotateArray(count);
            rotateCount++;
        }
        printArr(array);
    }

    private static void rotateArray(int rotateCount) {

        // 탐색하는 라인에 따라 범위가 달라짐 -> m과 n을 따로 저장
        int m = M;
        int n = N;
        int curLine = 0;

        while (curLine < rotateCount) {

            int x = curLine;
            int y = curLine;

            int idx = 1; // 탐색할 수의 개수
            int dir = 0; // dx, dy의 방향을 바꾸기 위한 변수
            int first = array[x][y];
            int loop = (m + n - 2) * 2;

            while (idx < loop + 1) {

                int nx = x + dx[dir];
                int ny = y + dy[dir];

                // 범위를 벗어나는 경우 체크
                if (nx < curLine || ny < curLine || nx >= N - curLine || ny >= M - curLine) {
                    dir = (dir + 1) % 4;
                    nx = x + dx[dir];
                    ny = y + dy[dir];
                }

                array[x][y] = array[nx][ny];
                x = nx;
                y = ny;
                idx++;
            }

            // 탐색할 크기 조정
            m -= 2;
            n -= 2;
            
            // 첫번째 요소 저장
            array[curLine + 1][curLine] = first;
            curLine++;

        }
    }

    private static void printArr(int[][] arr) {
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                System.out.print(arr[i][j] + " ");
            }
            System.out.println();
        }
    }
}

 

 

마무리

코드를 여러 번 갈아엎고 천천히 다시 풀어보며 완성할 수 있었다. 너무 어려웠던 문제였다. 그래도 탐색 과정을 이해하며 풀 수 있었다.  다시 한번 시도 해보면서 더 좋은 방법을 생각해 봐야겠다!

728x90
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크