문제 번호
알고리즘 분류
문제 풀이
구현 문제이다. 언젠가 풀어본 거 같지만 안 풀려있었다.
주어진 배열을 회전해야 하는데 위쪽 부분, 왼쪽 부분, 아래쪽 부분, 오른쪽 부분 이렇게 4 부분으로 나누어서 보기로 했다.
제일 밖에 있는 4개의 영역이 회전하고 크기를 줄여가면서 똑같이 회전하면 된다.
우선 윗부분을 살펴본다. 오른쪽에 있는 숫자를 왼쪽에서 받아야 한다. 그런데 가장 오른쪽에 있는 A[1][5]는 오른쪽에서 오는 것이 아니라 한 칸 아래 있는 숫자가 온다.
그다음 왼쪽 부분을 살펴보자. 위쪽에 있는 숫자를 아래쪽에서 받아야 한다. 그런데 가장 위에 있는 A[1][1]은 위쪽에서 오는 것이 아니라 오른쪽에 있는 숫자가 온다.
남아있는 아랫부분, 오른쪽 부분 역시 1개의 칸은 나머지 칸들과 다르게 숫자를 받아와야 한다.
그래서 각 4개의 부분의 숫자를 변경할 때 시작하는 부분을 한 칸 띄워놓고 시작하기로 했다. limit은 한 단계씩 작아지는 사각형을 표현하기 위함이다. 예를 들어 윗부분의 경우를 살펴보자.
for (let limit = 0; limit < Math.floor(min / 2); limit++) {
// 윗줄.
for (let j = (M - 2) - limit; j >= 0 + limit; j--) {
temp[0 + limit][j] = arr[0 + limit][j + 1];
}
윗 부분의 가장 오른쪽 칸은 A[1][5]이지만 위의 for문은 A[1][4]부터 값을 채운다. 왜냐하면 A[1][5]를 제외한 나머지 값들은 오른쪽에서 값을 받아온다는 공통된 방식을 취하지만 A[1][5]'만' 아래쪽에서 값을 받아오는 방식을 취하기 때문이다.
그럼 A[1][5]는 어떻게 값을 변경할 것인가?
오른쪽 부분의 값을 변경할 때를 살펴보자. 오른쪽 부분역시 A[4][5]를 제외한 모든 값들은 아래에서 위로 값을 받아온다. 이때 윗부분을 변경할때 제외했던 A [1][5]의 값이 변경된다.
// 오른쪽.
for (let j = (N - 2) - limit; j >= 0 + limit; j--) {
temp[j][(M - 1) - limit] = arr[j + 1][(M - 1) - limit];
}
결과적으로 각 4 부분의 값을 변경할 때 시작지점을 1칸씩 띄워 놓고 시작했는데 이때 변경되지 않는 '모서리'들은 다른 부분을 변경할때 채워지게 된다.
전체 코드
const input = require('fs').readFileSync('dev/stdin').toString().trim().split('\n');
const [N, M, R] = input[0].split(' ').map(Number);
let arr = input.slice(1).map(_ => _.trim().split(' ').map(Number));
function main() {
let answer = '';
let ret = [...arr];
for(let i=0; i<R; i++) {
ret = routate(arr);
arr = [...ret];
// console.log(answer.join('\n'))
// console.log("done")
}
ret.forEach(e => {
answer += e.join(' ') + '\n';
})
return console.log(answer.trim())
}
function routate(arr) { // 90000 000
let min = Math.min(N, M)
// 나눗셈으로 밀기.
// 각 모서리 시작점은 다른애가 채워줌.
let temp = new Array(N).fill(null).map(_ => new Array(M).fill(0));
for (let limit = 0; limit < Math.floor(min / 2); limit++) {
// 윗줄.
for (let j = (M - 2) - limit; j >= 0 + limit; j--) {
temp[0 + limit][j] = arr[0 + limit][j + 1];
}
// 왼쪽.
for (let j = 1 + limit; j < N - limit; j++) {
temp[j][0 + limit] = arr[j - 1][0 + limit];
}
// 아래
for (let j = 1 + limit; j < M - limit; j++) {
temp[(N - 1) - limit][j] = arr[(N - 1) - limit][j - 1];
}
// 오른쪽.
for (let j = (N - 2) - limit; j >= 0 + limit; j--) {
temp[j][(M - 1) - limit] = arr[j + 1][(M - 1) - limit];
}
}
// temp.forEach(e => {
// console.log(e.join(' '))
// })
return temp;
}
main();
특이사항
사각형이 줄어드는 것과 사각형을 4개의 영역으로 잘 나눴다면 어려움 없이 풀 수 있었다.
'Algorithm > BaeKJoon' 카테고리의 다른 글
[JS][백준]1166_선물 (0) | 2022.07.05 |
---|---|
[JS][백준]16938_캠프 준비 (0) | 2022.07.05 |
[JS][백준]16719_ZOAC (0) | 2022.06.15 |
[JS][백준]16206_롤케이크 (0) | 2022.06.15 |
[JS][백준]1167_트리의 지름 (0) | 2022.06.09 |