흙금이네 블로그

[BOJ] 16926 - 배열 돌리기 1 (Python, JavaScript) 본문

알고리즘

[BOJ] 16926 - 배열 돌리기 1 (Python, JavaScript)

흙금 2023. 1. 18. 23:49

 

 

아이디어

 

입력 받은 2차원 배열을 바깥쪽부터 안쪽으로 한 층씩 값을 R만큼 이동하여 새로운 2차원 리스트에 저장한다.

 

 

풀이 #1 (Python)

 

원래 배열을 2차원 리스트 arr에 저장하고, arr과 같은 크기로 0으로 채워진 2차원 리스트 res를 생성한다.

N과 M 중 더 작은 값을 2로 나눈 값만큼 for문을 반복하면서 리스트 바깥쪽에서 안쪽으로 접근한다.

i, j는 현재 저장할 arr의 숫자 위치를 가리키고, r, c는 원래 위치에서 R만큼 회전하여 res에 저장할 위치를 가리킨다.

d1과 d2는 하우상좌 순으로 인덱스 변화 값이 담긴 delta의 인덱스를 저장하는 변수로, 각각 arr과 res의 방향을 나타낸다.

 

R만큼 회전한 위치를 r과 c에 저장하고, 현재 층의 값들을 모두 채울 때까지 while문을 반복하며 값을 채워 나간다.

현재 돌고 있는 층의 범위를 벗어나면 방향을 전환하고, i와 j, r과 c 각각 다음 위치를 가리키도록 한다.

n과 m은 현재 돌고 있는 층의 크기를 나타내며, 두 값 모두 2만큼씩 감소하고 다음 반복문을 실행한다.

 

코드를 작성하는 것보다 작성한 코드를 설명하는 게 더 어려운 것 같다.

 

import sys

input = sys.stdin.readline

delta = [(1, 0), (0, 1), (-1, 0), (0, -1)]

N, M, R = map(int, input().split())
arr = [list(map(int, input().split())) for _ in range(N)]
res = [[0]*M for _ in range(N)]
n, m = N, M
for k in range(min(N, M)//2):
    i = j = r = c = k
    d1 = d2 = 0
    di, dj = delta[0]
    dr, dc = di, dj
    for _ in range(R):
        if r+dr >= n+k or r+dr < k or c+dc >= m+k or c+dc < k:
            d2 = (d2+1)%4
            dr, dc = delta[d2]
        r, c = r+dr, c+dc
    while not res[r][c]:
        res[r][c] = arr[i][j]
        if i+di >= n+k or i+di < k or j+dj >= m+k or j+dj < k:
            d1 = (d1+1)%4
            di, dj = delta[d1]
        if r+dr >= n+k or r+dr < k or c+dc >= m+k or c+dc < k:
            d2 = (d2+1)%4
            dr, dc = delta[d2]
        i, j = i+di, j+dj
        r, c = r+dr, c+dc
    n, m = n-2, m-2
for i in range(N):
    print(*res[i])

 

 

 

풀이 #2 (JavaScript)

 

풀이 #1 코드와 마찬가지로 입력 받은 배열 arr을 R만큼 회전하여 새로운 2차원 배열 res에 저장한다.

 

const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().split('\n');

const delta = [[1, 0], [0, 1], [-1, 0], [0, -1]];

const [N, M, R] = input[0].split(' ').map(Number);
let arr = [];
let res = [];
for (let i=1; i<=N; i++) {
    arr.push(input[i].split(' ').map(Number));
    let temp = [];
    for (let j=0; j<M; j++) {
        temp.push(0);
    }
    res.push(temp);
}
let [n, m] = [N, M];
for (let k=0; k<parseInt(Math.min(N, M)/2); k++) {
    let i = j = r = c = k;
    let d1 = d2 = 0;
    let [di, dj] = delta[0];
    let [dr, dc] = [di, dj];
    for (let t=0; t<R; t++) {
        if (r+dr >= n+k || r+dr < k || c+dc >= m+k || c+dc < k) {
            d2 = (d2+1)%4;
            [dr, dc] = delta[d2];
        }
        [r, c] = [r+dr, c+dc];
    }
    while (res[r][c] == 0) {
        res[r][c] = arr[i][j];
        if (i+di >= n+k || i+di < k || j+dj >= m+k || j+dj < k) {
            d1 = (d1+1)%4;
            [di, dj] = delta[d1];
        }
        if (r+dr >= n+k || r+dr < k || c+dc >= m+k || c+dc < k) {
            d2 = (d2+1)%4;
            [dr, dc] = delta[d2];
        }
        [i, j] = [i+di, j+dj];
        [r, c] = [r+dr, c+dc];
    }
    [n, m] = [n-2, m-2]
}
for (let i=0; i<N; i++) console.log(res[i].join(' '));

 

Comments