백준_16926_배열돌리기1

덤벨로퍼·2023년 12월 12일
0

코테

목록 보기
16/37

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

배열을 회전시키고 회전시키전에 이전에 있었던 배열을 복사해서 옮기는 방식

돌려야하는 그룹 갯수
시작은 xy 값이 같은 값에서 시작

import java.io.*;
import java.util.*;

public class Main {
    static int N, M, R;
    static int[][] map;
    static int lines;
    static int[] dx = {0, 1, 0, -1}; // 우 상 좌 하 (반시계)
    static int[] dy = {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());
            }
        }

        lines = Math.min(N, M)/2;

        for (int i = 0; i < R; i++) {
            roll();
        }

        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 roll() {
        for (int i = 0; i < lines; i++) {
            // 시작점을 왼쪽 상단 모서리로 선택
            int x = i;
            int y = i;

            int temp = map[x][y]; // 시작값 저장
            int dir = 0;

            while (dir < 4) {
                int nx = x + dx[dir]; // dx = {0, 1, 0, -1};
                int ny = y + dy[dir]; // dy = {1, 0, -1, 0};

                // 범위 벗어나면 방향 전환
                if (nx < i || nx >= N - i || ny < i || ny >= M - i) {
                    dir++;
                    continue;
                }

                // System.out.println("(" + x + ", " + y + ")");

                // 다음 칸의 값을 현재 칸으로 이동
                map[x][y] = map[nx][ny];
                x = nx;
                y = ny;
            }
            map[i + 1][i] = temp; // 시작값 처리 -> 모서리(i,i)에서 시작했으니 아래로 한칸 내려줌
        }

    }
}

코드 분석

방향에 있던 값을 현재 보고있는 값으로 옮기고 방향 인덱스 탐색

한쪽 방향으로 쭉 탐색하며 값을 바꾸다가 범위가 벗어나면 방향을 바꿈 (즉 탐색은 시계 , 값이동은 반시계)

  • 우측값을 좌측으로 ( arr[0][0] <- arr[0][1] <- arr[0][2] ...)
  • 아랫값을 위로 (arr[0][3] <- arr[1][3] <- arr[2][3] ...)
  • 좌측값을 우측으로 ( arr[4][3] <- arr[4][2] < arr[4][1] ..)
  • 윗값을 아래로
if (newX < N - i && newY < M - i && newX >= i && newY >= i)
  • i <= newX < N - i 즉 위아래로 움직일 수 있는 범위
  • i <= newY < M - i 즉 좌우로 움직일 수 있는 범위

방향에 관하여

static int[] dx = {0, 1, 0, -1}; // 우 상 좌 하 (반시계)
static int[] dy = {1, 0, -1, 0}; // 우 상 좌 하

static int[] dx = {0, -1, 0, 1}; // 우 하 좌 상 (시계)
static int[] dy = {1, 0, -1, 0}; // 우 하 좌 상
  • 이 문제는 배열을 반시계 방향으로 회전시키는 것
  • 방향 벡터도 반시계로 설정해야함!

1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
해당 순서로 탐색하며 새로운값을 채워나감!

👉 즉 다음칸의 값을 현재칸에 채우고 다음칸 탐색

L1

00(0, 0)
01(0, 1)
02(0, 2)
03(0, 3)
13(1, 3)
23(2, 3)
33(3, 3)
32(3, 2)
31(3, 1)
30(3, 0)
20(2, 0)
10(1, 0)

L2

11(1, 1)
12(1, 2)
22(2, 2)
21(2, 1)
profile
💪 점진적 과부하로 성장하는 개발자

0개의 댓글