코딩테스트/BOJ

[BOJ] 16935 배열돌리기 3 - JAVA

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

1. 문제

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

 

16935번: 배열 돌리기 3

크기가 N×M인 배열이 있을 때, 배열에 연산을 R번 적용하려고 한다. 연산은 총 6가지가 있다. 1번 연산은 배열을 상하 반전시키는 연산이다. 1 6 2 9 8 4 → 4 2 9 3 1 8 7 2 6 9 8 2 → 9 2 3 6 1 5 1 8 3 4 2 9 →

www.acmicpc.net

배열의 크기는 N*M이다. 주어진 R개의 연산을 순서대로 적용시킨 후 결과를 출력해야한다.

1번 연산 : 상하반전

2번 연산 : 좌우반전

3번 연산 : 오른쪽 90도 회전

4번 연산 : 왼쪽 90도 회전

5번 연산 : 4개의 부분배열로 나눠 그룹의 순서를 시계방향으로 이동

6번 연산 : 4개의 부분배열로 나눠 그룹의 순서를 반시계방향으로 이동


2. 풀이

상하함수

줄단위로 바꾼다.

private static void moveUD() {
    for (int i = 0; i < N / 2; i++) {
        int[] tmp = arr[i];
        arr[i] = arr[N - i - 1];
        arr[N - i - 1] = tmp;
    }
}

좌우함수

하나하나 바꿔준다.

private static void moveLR() {
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M / 2; j++) {
            int tmp = arr[i][j];
            arr[i][j] = arr[i][M - j - 1];
            arr[i][M - j - 1] = tmp;
        }
    }
}

 

90도 회전 함수

  • isRight변수로 오른쪽 회전(true)인지 왼쪽 회전(false)인지 체크한다.
  • 90도 회전이기때문에 가로와 세로길이가 변경된다. 따라서 새 M*N배열(tmp)을 만든다.
  • 오른쪽회전이라면 tmp[j][N-i-1]에, 왼쪽회전이라면 tmp[M-j-1][i]에 저장한다.
  • 마지막으로 static arr, M,N을 현재 값으로 바꿔준다. 

private static void turn(boolean isRight) {
    int tmp[][] = new int[M][N];
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            if(isRight) tmp[j][N-i-1] = arr[i][j];
            else tmp[M-j-1][i] = arr[i][j];
        }
    }
    arr = tmp;

    int num = M;
    M = N;
    N = num;
}

 

부분배열 회전 함수

  • 방향에 따라서 부분배열시작점과 이동값을 순서대로 초기화한다.
    • ex) 시계방향은 처음 (0,0)에서 시작한 배열이 오른쪽으로 이동하므로 (0,halfN) 저장
  • 시계방향 : 오른쪽-아래-왼쪽-위
  • 반시계방향 : 아래-왼쪽-위-오른쪽

private static void divide(boolean isRight) {
    int[][] tmp = new int[N][M];
    int[][] deltas;
    int halfN = N/2;
    int halfM = M/2;

    if(isRight){
        divideIdx = new int[][]{{0, 0}, {0, halfM}, {halfN, halfM}, {halfN, 0}};
        deltas = new int[][]{{0, halfM}, {halfN, 0}, {0, -halfM}, {-halfN, 0}};

    }else {
        divideIdx = new int[][]{{0, 0}, {halfN, 0}, {halfN, halfM}, {0, halfM}};
        deltas = new int[][]{{halfN, 0}, {0, halfM}, {-halfN, 0}, {0, -halfM}};
    }

    for(int k=0;k<4;k++){
        for (int i = divideIdx[k][0]; i < divideIdx[k][0]+N/2; i++) {
            for (int j = divideIdx[k][1]; j < divideIdx[k][1]+M/2; j++) {
                tmp[i+deltas[k][0]][j+deltas[k][1]] = arr[i][j];
            }
        }
    }

    arr = tmp;
}

 

메인함수

  • swtich case로 명령을 받을 때마다 회전시킨다.
public static void main(String[] args) throws Exception {
    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());
        }
    }

    st = new StringTokenizer(in.readLine());
    for (int r = 0; r < R; r++) {
        switch (st.nextToken().charAt(0)) {
            case '1':
                moveUD();
                break;
            case '2':
                moveLR();
                break;
            case '3':
                turn(true);
                break;
            case '4':
                turn(false);
                break;
            case '5':
                divide(true);
                break;
            case '6':
                divide(false);
                break;
        }
    }

    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.print(sb);
}

3. 결과

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

[BOJ] 2491 수열 - JAVA  (0) 2022.02.12
[BOJ] 17406 배열돌리기 4 - JAVA  (0) 2022.02.12
[BOJ] 16926 배열돌리기1 - JAVA  (0) 2022.02.12
[BOJ] 2563 색종이 - JAVA  (0) 2022.02.11
[BOJ] 2564 경비원 - JAVA  (0) 2022.02.11

댓글