풀이
const fs = require('fs');
const filePath = process.platform === 'linux' ? '/dev/stdin' : './input.txt';
// const filePath = process.platform === 'linux' ? '/dev/stdin' : 'BOJ/input.txt';
const input = fs.readFileSync(filePath).toString().trim().split('\n');
const [N, M, R] = input.shift().split(' ').map(Number);
const opList = input.pop().split(' ').map(Number);
let arr = input.map((row) => row.split(' ').map(Number));
/**
* 1. 배열을 상하 반전시키는 함수이다.
*/
function flipUD() {
const totalRow = arr.length;
const result = [];
for (let i = totalRow - 1; i >= 0; i--) {
result.push([...arr[i]]);
}
arr = result;
}
/**
* 2. 배열을 좌우 반전시키는 함수이다.
*/
function flipLR() {
const totalRow = arr.length;
const result = [];
for (let i = 0; i < totalRow; i++) {
result.push([...arr[i]].reverse());
}
arr = result;
}
/**
* 3. 오른쪽으로 90도 회전시키는 함수이다.
*/
function rotateRight() {
const totalRow = arr.length;
const totalCol = arr[0].length;
const result = [];
for (let j = 0; j < totalCol; j++) {
const row = [];
for (let i = totalRow - 1; i >= 0; i--) {
row.push(arr[i][j]);
}
result.push(row);
}
arr = result;
}
/**
* 4. 왼쪽으로 90도 회전시키는 함수이다.
*/
function rotateLeft() {
const totalRow = arr.length;
const totalCol = arr[0].length;
const result = [];
for (let j = totalCol - 1; j >= 0; j--) {
const row = [];
for (let i = 0; i < totalRow; i++) {
row.push(arr[i][j]);
}
result.push(row);
}
arr = result;
}
/**
* 5, 6번 연산을 수행하려면 배열을 크기가 N/2×M/2인 4개의 부분 배열로 나눠야 한다.
*
* 5. 1번 그룹의 부분 배열을 2번 그룹 위치로, 2번을 3번으로, 3번을 4번으로, 4번을 1번으로 이동시키는 함수이다.
*/
function rotateQuadrantsClockwise() {
const totalRow = arr.length;
const totalCol = arr[0].length;
const rowHalf = totalRow / 2;
const colHalf = totalCol / 2;
const result = Array.from({ length: totalRow }, () =>
Array.from({ length: totalCol })
);
// 1번 그룹 -> 2번 그룹 위치로 이동
for (let i = 0; i < rowHalf; i++) {
for (let j = 0; j < colHalf; j++) {
result[i][j + colHalf] = arr[i][j];
}
}
// 2번 그룹 -> 3번 그룹 위치로 이동
for (let i = 0; i < totalRow / 2; i++) {
for (let j = colHalf; j < totalCol; j++) {
result[i + rowHalf][j] = arr[i][j];
}
}
// 3번 그룹 -> 4번 그룹 위치로 이동
for (let i = rowHalf; i < totalRow; i++) {
for (let j = colHalf; j < totalCol; j++) {
result[i][j - colHalf] = arr[i][j];
}
}
// 4번 그룹 -> 1번 그룹 위치로 이동
for (let i = rowHalf; i < totalRow; i++) {
for (let j = 0; j < colHalf; j++) {
result[i - rowHalf][j] = arr[i][j];
}
}
arr = result;
}
/**
* 6. 1번 그룹의 부분 배열을 4번 그룹 위치로, 4번을 3번으로, 3번을 2번으로, 2번을 1번으로 이동시키는 함수이다.
*/
function rotateQuadrantsCounterClockwise() {
const totalRow = arr.length;
const totalCol = arr[0].length;
const rowHalf = totalRow / 2;
const colHalf = totalCol / 2;
const result = Array.from({ length: totalRow }, () =>
Array.from({ length: totalCol })
);
// 1번 그룹 -> 4번 그룹 위치로 이동
for (let i = 0; i < rowHalf; i++) {
for (let j = 0; j < colHalf; j++) {
result[i + rowHalf][j] = arr[i][j];
}
}
// 2번 그룹 -> 1번 그룹 위치로 이동
for (let i = 0; i < rowHalf; i++) {
for (let j = colHalf; j < totalCol; j++) {
result[i][j - colHalf] = arr[i][j];
}
}
// 3번 그룹 -> 2번 그룹 위치로 이동
for (let i = rowHalf; i < totalRow; i++) {
for (let j = colHalf; j < totalCol; j++) {
result[i - rowHalf][j] = arr[i][j];
}
}
// 4번 그룹 -> 3번 그룹 위치로 이동
for (let i = rowHalf; i < totalRow; i++) {
for (let j = 0; j < colHalf; j++) {
result[i][j + colHalf] = arr[i][j];
}
}
arr = result;
}
/**
* 결과를 출력하는 함수이다.
*/
function printResult() {
const result = arr.map((row) => row.join(' ')).join('\n');
console.log(result);
}
function solution() {
opList.forEach((op) => {
switch (op) {
case 1:
flipUD();
break;
case 2:
flipLR();
break;
case 3:
rotateRight();
break;
case 4:
rotateLeft();
break;
case 5:
rotateQuadrantsClockwise();
break;
case 6:
rotateQuadrantsCounterClockwise();
break;
default:
break;
}
});
printResult();
}
solution();
정말 문제 그대로 구현하면 되는 문제이다.
다만, 주어지는 배열이 정사각형이 아닐 수 있으므로 인덱스를 다루는데 조심해야 한다.
회전하면 행의 개수와 열의 개수가 달라질 수도 있기 때문이다.
`flipUD()`
/**
* 1. 배열을 상하 반전시키는 함수이다.
*/
function flipUD() {
const totalRow = arr.length;
const result = [];
for (let i = totalRow - 1; i >= 0; i--) {
result.push([...arr[i]]);
}
arr = result;
}
먼저, 1번 연산인 배열을 상하 반전시키는 연산이다.
기존 배열의 마지막 행부터 거꾸로 새로운 배열에 넣어주었다.
`flipLR()`
/**
* 2. 배열을 좌우 반전시키는 함수이다.
*/
function flipLR() {
const totalRow = arr.length;
const result = [];
for (let i = 0; i < totalRow; i++) {
result.push([...arr[i]].reverse());
}
arr = result;
}
2번 연산인 배열을 좌우 반전시키는 연산이다.
여기서 주의할 것은 reverse() 함수는 원본 배열을 바꾸기 때문에,
전개 연산자를 이용해 얕은 복사를 해준 후, 반전시켜주었다.
물론, 연산 후의 배열로 원본 배열을 대체하기 때문에 상관은 없지만
중간에 한 번 꼬이면 힘들어지기 때문에 방어적으로 코드를 작성하였다.
`rotateRight()`
/**
* 3. 오른쪽으로 90도 회전시키는 함수이다.
*/
function rotateRight() {
const totalRow = arr.length;
const totalCol = arr[0].length;
const result = [];
for (let j = 0; j < totalCol; j++) {
const row = [];
for (let i = totalRow - 1; i >= 0; i--) {
row.push(arr[i][j]);
}
result.push(row);
}
arr = result;
}
3번 연산인 배열을 오른쪽으로 90도 회전시키는 연산이다.
앞으로 계속 나오겠지만, `N`과 `M`이 입력에도 주어졌음에도 `totalRow`랑 `totalCol`을 따로 선언해주었다.
배열이 정사각형이 아닐 경우, 이전 연산에 의해서 회전하면서 행과 열이 바뀔 수 있기 때문이다.
오른쪽으로 90도 회전하게 되면,
첫 번째 열이 첫 번째 행에 오게 되므로, 그 방향을 생각하면서 구현하면 된다.
`rotateLeft()`
/**
* 4. 왼쪽으로 90도 회전시키는 함수이다.
*/
function rotateLeft() {
const totalRow = arr.length;
const totalCol = arr[0].length;
const result = [];
for (let j = totalCol - 1; j >= 0; j--) {
const row = [];
for (let i = 0; i < totalRow; i++) {
row.push(arr[i][j]);
}
result.push(row);
}
arr = result;
}
4번 연산인 배열을 왼쪽으로 90도 회전시키는 연산이다.
마지막 열이 첫 번째 행에 오게 되므로, 그 방향을 생각하면서 구현하면 된다.
`rotateRight()` 연산을 구현했으면 똑같은 방법으로 구현하면 되서 어렵지 않다.
`rotateQuadrantsClockwise()`
/**
* 5, 6번 연산을 수행하려면 배열을 크기가 N/2×M/2인 4개의 부분 배열로 나눠야 한다.
*
* 5. 1번 그룹의 부분 배열을 2번 그룹 위치로, 2번을 3번으로, 3번을 4번으로, 4번을 1번으로 이동시키는 함수이다.
*/
function rotateQuadrantsClockwise() {
const totalRow = arr.length;
const totalCol = arr[0].length;
const rowHalf = totalRow / 2;
const colHalf = totalCol / 2;
const result = Array.from({ length: totalRow }, () =>
Array.from({ length: totalCol })
);
// 1번 그룹 -> 2번 그룹 위치로 이동
for (let i = 0; i < rowHalf; i++) {
for (let j = 0; j < colHalf; j++) {
result[i][j + colHalf] = arr[i][j];
}
}
// 2번 그룹 -> 3번 그룹 위치로 이동
for (let i = 0; i < totalRow / 2; i++) {
for (let j = colHalf; j < totalCol; j++) {
result[i + rowHalf][j] = arr[i][j];
}
}
// 3번 그룹 -> 4번 그룹 위치로 이동
for (let i = rowHalf; i < totalRow; i++) {
for (let j = colHalf; j < totalCol; j++) {
result[i][j - colHalf] = arr[i][j];
}
}
// 4번 그룹 -> 1번 그룹 위치로 이동
for (let i = rowHalf; i < totalRow; i++) {
for (let j = 0; j < colHalf; j++) {
result[i - rowHalf][j] = arr[i][j];
}
}
arr = result;
}
5번 연산인 시계 방향으로 각 그룹을 회전하는 연산이다.
문제 그대로 네 그룹으로 나눈 뒤, 각 그룹을 따로따로 새로운 배열에 값을 넣어주었다.
인덱스만 조심하면 크게 어려울 것 없다.
`rotateQuadrantsCounterClockwise()`
/**
* 6. 1번 그룹의 부분 배열을 4번 그룹 위치로, 4번을 3번으로, 3번을 2번으로, 2번을 1번으로 이동시키는 함수이다.
*/
function rotateQuadrantsCounterClockwise() {
const totalRow = arr.length;
const totalCol = arr[0].length;
const rowHalf = totalRow / 2;
const colHalf = totalCol / 2;
const result = Array.from({ length: totalRow }, () =>
Array.from({ length: totalCol })
);
// 1번 그룹 -> 4번 그룹 위치로 이동
for (let i = 0; i < rowHalf; i++) {
for (let j = 0; j < colHalf; j++) {
result[i + rowHalf][j] = arr[i][j];
}
}
// 2번 그룹 -> 1번 그룹 위치로 이동
for (let i = 0; i < rowHalf; i++) {
for (let j = colHalf; j < totalCol; j++) {
result[i][j - colHalf] = arr[i][j];
}
}
// 3번 그룹 -> 2번 그룹 위치로 이동
for (let i = rowHalf; i < totalRow; i++) {
for (let j = colHalf; j < totalCol; j++) {
result[i - rowHalf][j] = arr[i][j];
}
}
// 4번 그룹 -> 3번 그룹 위치로 이동
for (let i = rowHalf; i < totalRow; i++) {
for (let j = 0; j < colHalf; j++) {
result[i][j + colHalf] = arr[i][j];
}
}
arr = result;
}
6번 연산인 반시계 방향으로 각 그룹을 회전시키는 연산이다.
5번 연산을 구현했다면, 똑같은 형태로 구현이 가능하다.
`printResult()`
/**
* 결과를 출력하는 함수이다.
*/
function printResult() {
const result = arr.map((row) => row.join(' ')).join('\n');
console.log(result);
}
결과를 출력하는 함수이다.
배열을 순회하면서 출력해줘도 되지만, 한 문자열로 만든뒤 한번에 출력한 이유가 있다.
`console.log()`도 함수이기 때문에, 연산 비용이 존재한다.
실제로 출력해야 할 값이 많은 문제에서 따로따로 출력할 경우 시간초과가 발생하는 경우가 있다.
그러기에 한 문자열로 만든 뒤 출력하는 것을 추천한다.
`solution()`
function solution() {
opList.forEach((op) => {
switch (op) {
case 1:
flipUD();
break;
case 2:
flipLR();
break;
case 3:
rotateRight();
break;
case 4:
rotateLeft();
break;
case 5:
rotateQuadrantsClockwise();
break;
case 6:
rotateQuadrantsCounterClockwise();
break;
default:
break;
}
});
printResult();
}
메인 함수인 solution 함수이다.
각 번호에 맞는 연산 함수를 호출해주면 된다.
마지막으로 `printResult()` 함수를 호출해 결과를 출력해주면 완성!
'PS > 백준' 카테고리의 다른 글
백준 / 3190번 / 뱀 / JS (0) | 2025.09.16 |
---|---|
백준 / 투 포인터 / 22862번 / 가장 긴 짝수 연속한 부분 수열 (large) / JS (0) | 2025.04.07 |
백준 / 수학 / 11444번 / 피보나치 수 6 / JS (1) | 2025.01.13 |
백준 / 그래프 / 2206번 / 벽 부수고 이동하기 / JS (0) | 2025.01.11 |