백준 - 배열 돌리기 1

greenTea·2023년 8월 31일
0

첫번재 시도

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

public class Main {
    static int[][] map;
    static int N, M, R;

    static int[] x = new int[]{0, 1, 0, -1};
    static int[] y = new int[]{1, 0, -1, 0};

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

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

        map = new int[N][M];

        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < M; j++) {
                map[i][j] = Integer.parseInt(st.nextToken());
            }
        }
        start();
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                System.out.print(map[i][j]+" ");
            }
            System.out.println();
        }


    }

    public static void start() {

        for (int i = 0; i < R ; i++) {
            boolean[][] check = new boolean[N][M];
            int[][] newArr = new int[N][M];
            rotate(check, newArr);
            map = newArr;
        }


    }



    private static void rotate(boolean[][] check, int[][] newArr) {
        for (int i = 0, j = 0; i < N && j < M; i++, j++) {
            if (!check[i][j]) {
                int cx = j;
                int cy = i;
                for (int k = 0; k < 4; k++) {
                    int px = x[k];
                    int py = y[k];
                    while (cx+px >= 0 && cx+px < M && cy+py >= 0 && cy+py < N && !check[cy+py][cx+px]){
                        newArr[cy+py][cx+px]=map[cy][cx];
                        check[cy+py][cx+px]=true;
                        cy = cy+py;
                        cx = cx+px;
                    }
                }
            }
        }
    }

}

😰처음에는 같은 크기의 배열을 만들어서 이미 방문한 곳은 방문하지 못하게 처리하였으며 또한 이동한 값을 다시 옮겨주는 작업으로 처리하였습니다.
rotate의 경우에는 지난 간 곳이 아니라면 x,y 배열에서 정의한 대로 (실제 백준 사이트의 그림처럼) 직접 하나씩 옮겨가며 계산하였습니다.

그러나 위 방식대로 하면 메모리를 엄청나게 잡아먹는다는 단점이 있기에 다른 고민하고 찾아보았습니다.

두번째 시도

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

public class Main {
    static int[][] map;
    static int N, M, R;

    static int[] y = new int[]{0, 1, 0, -1};
    static int[] x = new int[]{1, 0, -1, 0};

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

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

        map = new int[N][M];

        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < M; j++) {
                map[i][j] = Integer.parseInt(st.nextToken());
            }
        }
        int group = Math.min(N, M) / 2;
        rotate(group);
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                System.out.print(map[i][j] + " ");
            }
            System.out.println();
        }


    }


    private static void rotate(int group) {
        for (int k = 0; k < R; k++) {
            for (int i = 0; i < group; i++) {
                int cx = i;
                int cy = i;
                int lastValue = map[cy][cx];
                int direct = 0;

                while (direct < 4) {

                    int px = cx + x[direct];
                    int py = cy + y[direct];

                    if (px >= i && px < M-i && py >= i && py < N-i) {
                        map[cy][cx] = map[py][px];
                        cx = px;
                        cy = py;
                    } else {
                        direct++;
                    }

                }

                map[cy+1][cx] = lastValue;
            }
        }

    }

}

🤔첫 번째 방식과 비교하여 메모리 사용량을 대폭 줄일 수 있었습니다.(시간도 확연히 줄었습니다.)
배열을 생성하지 않고 기존 배열을 이용하여 푸는 방식으로
백준에서 설명하는 그림처럼 이동하며 푼다기보다는 반대로 움직이면서 풀이 한 것을 확인 할 수 있습니다.

출처 및 참고자료

백준 - 배열 돌리기1
티스토리 - 츄르 사려고 코딩하는 집사

profile
greenTea입니다.

0개의 댓글