백준 - 16935번(배열 돌리기 3)

최지홍·2022년 2월 9일
0

백준

목록 보기
38/145

문제 출처: https://www.acmicpc.net/problem/16935


문제

  • 크기가 N×M인 배열이 있을 때, 배열에 연산을 R번 적용하려고 한다. 연산은 총 6가지가 있다.
  • 1번 연산은 배열을 상하 반전시키는 연산이다.
  • 2번 연산은 배열을 좌우 반전시키는 연산이다.
  • 3번 연산은 오른쪽으로 90도 회전시키는 연산이다.
  • 4번 연산은 왼쪽으로 90도 회전시키는 연산이다.
  • 5, 6번 연산을 수행하려면 배열을 크기가 N/2×M/2인 4개의 부분 배열로 나눠야 한다. 아래 그림은 크기가 6×8인 배열을 4개의 그룹으로 나눈 것이고, 1부터 4까지의 수로 나타냈다.
  • 5번 연산은 1번 그룹의 부분 배열을 2번 그룹 위치로, 2번을 3번으로, 3번을 4번으로, 4번을 1번으로 이동시키는 연산이다.
  • 6번 연산은 1번 그룹의 부분 배열을 4번 그룹 위치로, 4번을 3번으로, 3번을 2번으로, 2번을 1번으로 이동시키는 연산이다.

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

public class Main {

    public static void main(String[] args) throws IOException {
        StringBuilder sb = new StringBuilder();
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer tokenizer = new StringTokenizer(reader.readLine());
        int N = Integer.parseInt(tokenizer.nextToken());
        int M = Integer.parseInt(tokenizer.nextToken());
        int R = Integer.parseInt(tokenizer.nextToken());
        int[][] target = new int[N][M];
        for (int i = 0; i < N; i++) {
            tokenizer = new StringTokenizer(reader.readLine());
            for (int j = 0; j < M; j++) {
                target[i][j] = Integer.parseInt(tokenizer.nextToken());
            }
        }

        tokenizer = new StringTokenizer(reader.readLine());
        int[] command = new int[R];
        int[][] result = new int[N][M];
        for (int i = 0; i < R; i++) {
            command[i] = Integer.parseInt(tokenizer.nextToken());
            switch (command[i]) {
                case 1:
                    result = calc1(target, N, M);
                    break;

                case 2:
                    result = calc2(target, N, M);
                    break;

                case 3:
                    result = calc3(target, N, M);
                    break;

                case 4:
                    result = calc4(target, N, M);
                    break;

                case 5:
                    result = calc5(target, N, M);
                    break;

                case 6:
                    result = calc6(target, N, M);
                    break;
            }

            target = result;
            N = target.length;
            M = target[0].length;
        }

        for (int[] row : result) {
            for (int col : row) {
                sb.append(col).append(" ");
            }
            sb.append("\n");
        }

        System.out.println(sb);
    }

    private static int[][] calc1(int[][] target, int N, int M) {
        int[][] result = new int[N][M];

        for (int j = 0; j < M; j++) {
            for (int i = 0; i < N; i++) {
                result[i][j] = target[N - i - 1][j];
            }
        }

        return result;
    }

    private static int[][] calc2(int[][] target, int N, int M) {
        int[][] result = new int[N][M];

        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                result[i][j] = target[i][M - j - 1];
            }
        }

        return result;
    }

    private static int[][] calc3(int[][] target, int N, int M) {
        int[][] result = new int[M][N];

        for (int j = 0; j < M; j++) {
            for (int i = 0; i < N; i++) {
                result[j][N - i - 1] = target[i][j];
            }
        }

        return result;
    }

    private static int[][] calc4(int[][] target, int N, int M) {
        int[][] result = new int[M][N];

        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                result[M - j - 1][i] = target[i][j];
            }
        }

        return result;
    }

    private static int[][] calc5(int[][] target, int N, int M) {
        int[][] result = new int[N][M];

        for (int i = 0; i < N / 2; i++) {
            for (int j = 0; j < M / 2; j++) { // 1
                result[i][j + M / 2] = target[i][j];
            }
            for (int j = M / 2; j < M; j++) { // 2
                result[i + N / 2][j] = target[i][j];
            }
        }

        for (int i = N / 2; i < N; i++) { // 3
            for (int j = M / 2; j < M; j++) {
                result[i][j - M / 2] = target[i][j];
            }
            for (int j = 0; j < M / 2; j++) { // 4
                result[i - N / 2][j] = target[i][j];
            }
        }

        return result;
    }

    private static int[][] calc6(int[][] target, int N, int M) {
        int[][] result = new int[N][M];

        for (int i = 0; i < N / 2; i++) {
            for (int j = 0; j < M / 2; j++) { // 1
                result[i + N / 2][j] = target[i][j];
            }
            for (int j = M / 2; j < M; j++) { // 2
                result[i][j - M / 2] = target[i][j];
            }
        }

        for (int i = N / 2; i < N; i++) {
            for (int j = M / 2; j < M; j++) { // 3
                result[i - N / 2][j] = target[i][j];
            }
            for (int j = 0; j < M / 2; j++) { // 4
                result[i][j + M / 2] = target[i][j];
            }
        }

        return result;
    }

}

  • 직전의 배열 돌리기 1보다 뭔가 더 쉬운 느낌이었다.
  • 입력 배열과 같은 크기의 2차원 배열을 만들고 해당하는 좌표로 이동하여 값을 구할 수 있었다.
profile
백엔드 개발자가 되자!

0개의 댓글