코딩테스트/BOJ

[BOJ] 16926 배열돌리기1 - JAVA

5월._. 2022. 2. 12.
728x90

1. 문제

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

 

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

크기 N*M배열을 반시계 방향으로 R번 회전시킨 결과를 출력한다.


2. 풀이

  1. N*M 배열을 R번 회전시킨다.
    • 한 번 회전시킬 때마다 가장 바깥쪽에서부터 안쪽까지 한 줄 한 줄 돌린다.
    • 따라서 한 번의 회전 당 turnArr(회전메서드)를 부르는 횟수는 더 작은 변의 절반만큼이다. 
  2. 어떤 사각형이든 항상 시작점은 행과 열의 번호가 동일하므로 x와 y에 둘 다 i를 넣고 따로 num변수에 arr[y][x]값을 담아둔 뒤 반복을 시작한다.
  3. 다음으로 방문할 x,y를 구하고, 구한 값이 범위에 벗어난다면 d+1을 해 방향을 틀어서 반복문의 처음으로 돌아간다.
    • 여기서 d는 이동하는 방향을 넣어놓은 deltas에 접근하는 변수다. deltas는 아래, 오른쪽, 위, 왼쪽 순서로 x와 y의 변화값을 담은 배열이다.
    • x값은 M과, y값은 N과 관련있다. (주의할 것)
  4. d가 deltas의 길이와 똑같아질때까지 3을 반복한다. 

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

public class BOJ_16926_배열돌리기1 {
    static int[][] deltas = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};//아래, 오른쪽, 위, 왼쪽
    static int N, M, R;
    static int[][] arr;

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

        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        R = Integer.parseInt(st.nextToken());

        arr = new int[N][M];

        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(in.readLine());
            for (int j = 0; j < M; j++) {
                arr[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        //회전
        for (int r = 0; r < R; r++) {
            for (int i = 0; ; i++) {
                if (i >= N / 2 || i >= M / 2) break;
                turnArr(i);
            }
        }

        //출력
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                sb.append(arr[i][j]).append(" ");
            }
            sb.append("\n");
        }
        System.out.println(sb);

    }

    public static void turnArr(int i) {
        int y = i, x = i;
        int d = 0;//방향
        int num = arr[y][x];

        while (true) {
            if (d == 4) break;

            int tmpy = y + deltas[d][0];
            int tmpx = x + deltas[d][1];

            if (tmpx < i || tmpx >= M-i || tmpy < i || tmpy >= N-i) {
                ++d;
                continue;
            }

            int n = num;
            num = arr[tmpy][tmpx];
            arr[tmpy][tmpx] = n;

            y = tmpy;
            x = tmpx;
        }
    }
}

3. 결과

회전 문제는 항상 x,y가 각각 어떤 변수와 관련 있는지가 헷갈린다. 이런 문제는 주석으로라도 항상 x->열-> M 이런 식으로 적어놓고 풀어야겠다.

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

[BOJ] 17406 배열돌리기 4 - JAVA  (0) 2022.02.12
[BOJ] 16935 배열돌리기 3 - JAVA  (0) 2022.02.12
[BOJ] 2563 색종이 - JAVA  (0) 2022.02.11
[BOJ] 2564 경비원 - JAVA  (0) 2022.02.11
[BOJ] 2578 빙고 - JAVA  (0) 2022.02.11

댓글