백준 - 배열 돌리기 1

김준영·2025년 3월 27일

백준

목록 보기
15/27
post-thumbnail

문제 링크 ▶︎ 배열 돌리기1

문제 파악

문제의 가장 큰 특징은 레이어 별로 회전한다는 것이다. 가장 바깥에 존재하는 레이어는 해당 레이어끼리 시계방향으로 회전하고, 그 안의 레이어도 해당 레이어끼리 회전한다.
그리고 회전의 횟수만큼 반복문을 시행하기에는 최악의 경우 300 x 300 x 1000의 시행이 걸리기 때문에 회전 횟수만큼 반복문을 돌아서는 안될 것 같다.

접근 방법

  1. 우선 레이어별로 존재하는 좌표를 리스트에 저장한다. 회전 방향은 정해져있고, 모든 좌표의 방문 처리를 통해서 레이어별 방문을 시행한다.

  2. 남동북서 방향의 순서대로 존재하며, 조건을 넘어가는 좌표나 이미 방문한 좌표가 나오게 되면 방향을 바꿔주면 된다.

  3. 그렇게 모든 레이어에 대한 좌표를 리스트에 저장하고 나면, 회전 횟수만큼 순서대로 저장된 레이어의 좌표에 회전 횟수만큼 더한 좌표를 ans 배열에 저장하면 된다.

코드 구현

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

public class Main {
    public static int answer;
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        int n = Integer.parseInt(st.nextToken());
        int m = Integer.parseInt(st.nextToken());
        int r = Integer.parseInt(st.nextToken());
        int[][] grid = new int[n][m];
        int[][] answer = new int[n][m];
        for (int i = 0; i < n; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < m; j++) {
                grid[i][j] = Integer.parseInt(st.nextToken());
            }
        }
        List<List<int[]>> data = new ArrayList<>();
        boolean[][] visit = new boolean[n][m];
        int[][] dir = new int[][] {{1,0}, {0,1}, {-1,0}, {0,-1}};
        int temp = Math.min(m, n) / 2;
        for (int i = 0; i < temp; i++) {
            int y = i, x = i;
            visit[y][x] = true;
            List<int[]> lst = new ArrayList<>();
            lst.add(new int[]{y, x});
            int alt = 0;
            while (alt < 4) {
                y += dir[alt][0];
                x += dir[alt][1];
                if (0 <= y && 0 <= x && y < n && x < m && !visit[y][x]) {
                    visit[y][x] = true;
                    lst.add(new int[]{y, x});
                } else {
                    y -= dir[alt][0];
                    x -= dir[alt][1];
                    alt++;
                }
            }
            data.add(lst);
        }
        for (int i = 0; i < temp; i++) {
            for (int j = 0; j < data.get(i).size(); j++) {
                int y = data.get(i).get(j)[0];
                int x = data.get(i).get(j)[1];
                int k = (j + r) % data.get(i).size();
                answer[data.get(i).get(k)[0]][data.get(i).get(k)[1]] = grid[y][x];
            }
        }
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                System.out.print(answer[i][j] + " ");
            }
            System.out.println();
        }

    }
}

개선 사항

굳이 visit 방문 배열을 쓰지 않고 조건을 처리해서 레이어 이동을 구현할 수도 있었던 것 같다.

profile
junyoun9dev@gmail.com

0개의 댓글