알고리즘 연습

[알고리즘 연습] 백준 16926 (배열 돌리기 1, 자바스크립트)

산본개발자 2023. 5. 25. 10:17

문제

 

16926번: 배열 돌리기 1

크기가 N×M인 배열이 있을 때, 배열을 돌려보려고 한다. 배열은 다음과 같이 반시계 방향으로 돌려야 한다. A[1][1] ← A[1][2] ← A[1][3] ← A[1][4] ← A[1][5] ↓ ↑ A[2][1] A[2][2] ← A[2][3] ← A[2][4] A[2][5]

www.acmicpc.net


풀이

입력으로 주어진 N * M 배열을 R번 회전시킨 결과를 출력하는 문제이다. 회전은 반시계 방향으로 진행한다.

  •  한번의 회전을 수행할 때 몇 개의 네모 형태를 회전 시켜야 하는지가 핵심인 문제였고 이를 구현하기 위해 min(N, M) / 2 공식을 이용했다.
  • 처음에는 배열의 회전을 구현하기 위해 Queue를 사용하는 방법을 떠올렸다. 하지만, Queue를 사용하면 for문으로 배열을 순서대로 접근하는 것을 2번 수행해야 한다.
  • 회전을 구현할 때 원본 배열을 훼손시키지 않기 위해 임시 배열을 생성하였다.

소스 코드

const filePath = process.platform === "linux" ? "/dev/stdin" : "./input.txt";
const input = require("fs")
  .readFileSync(filePath)
  .toString()
  .trim()
  .split("\n");

const [N, M, R] = input[0].split(" ").map(Number);
const arr = Array.from({ length: N }, () => Array(M).fill(null));
let visited;
let r = 0;
let answer = "";

for (let i = 1; i <= N; i++) {
  const temp = input[i].split(" ").map(Number);
  for (let j = 0; j < M; j++) {
    arr[i - 1][j] = temp[j];
  }
}

while (r++ < R) {
  visited = Array.from({ length: N }, () => Array(M).fill(false));
  rotate();
}

for (let i = 0; i < N; i++) {
  answer += arr[i].join(" ");
  answer += "\n";
}

console.log(answer);

function rotate() {
  const temp = Array.from({ length: N }, () => Array(M).fill(null));
  const count = Math.floor(Math.min(M, N) / 2);

  for (let k = 0; k < count; k++) {
    let x = k;
    let y = k;

    while (!visited[x][y]) {
      visited[x][y] = true;

      if (x === k && y !== M - 1 - k) {
        temp[x][y] = arr[x][y + 1];
        y += 1;
      } else if (y === M - 1 - k && x !== N - 1 - k) {
        temp[x][y] = arr[x + 1][y];
        x += 1;
      } else if (x === N - 1 - k && y !== k) {
        temp[x][y] = arr[x][y - 1];
        y -= 1;
      } else if (y === k && x !== k) {
        temp[x][y] = arr[x - 1][y];
        x -= 1;
      }
    }
  }

  for (let i = 0; i < N; i++) {
    for (let j = 0; j < M; j++) {
      arr[i][j] = temp[i][j];
    }
  }
}