풀이
김영준
// rows * columns의 행렬이 있음 // x1 y1부터 x2 y2까지 해당하는 테두리를 시계방향으로 회전 // 쿼리를 수행한 후 제일 최솟값을 리턴 const rotation = ([x1, y1, x2, y2], arr) => { x1--; y1--; x2--; y2--; // 0이 아닌 1이 시작점이니까 1씩 감소 const newArr = arr.map((row) => [...row]); let min = arr[x1][y1]; // 최솟값 초기화 for(let i = y1; i < y2; i++){ newArr[x1][i+1] = arr[x1][i]; // 오른쪽으로 회전 if(arr[x1][i] < min) min = arr[x1][i]; } for(let i = x1; i < x2; i++){ newArr[i+1][y2] = arr[i][y2]; // 아래로 회전 if(arr[i][y2] < min) min = arr[i][y2]; } for(let i = y2; i > y1; i--){ newArr[x2][i-1] = arr[x2][i]; // 왼쪽으로 회전 if(arr[x2][i] < min) min = arr[x2][i]; } for(let i = x2; i > x1; i--){ newArr[i-1][y1] = arr[i][y1]; if(arr[i][y1] < min) min = arr[i][y1]; } return [newArr, min] } function solution(rows, columns, queries) { let arr = []; const answer = []; let count = 1; // 행렬을 만든다. for(let x = 0; x < rows; x++){ const row = []; for(let y = 0; y < columns; y++){ row.push(count++); } arr.push(row); } for(let i = 0; i < queries.length; i ++){ const [rotateArr, minVal] = rotation(queries[i], arr); arr = rotateArr.map((row) => [...row]); answer.push(minVal); } return answer; }
이종현
function solution(rows, columns, queries) { const answer = []; let arr = Array.from(new Array(rows + 1), () => new Array(columns + 1).fill(0) ); // 숫자 채우기 for (let i = 1; i <= rows; i++) { for (let j = 1; j <= columns; j++) { arr[i][j] = (i - 1) * columns + j; } } for (let tc = 0; tc < queries.length; tc++) { const [x1, y1, x2, y2] = queries[tc]; const stack = []; // 맨 위 직사각형 고르기 x1은 행 고정, y1이 y2 직전까지 1씩 증가 for (let i = y1; i < y2; i++) stack.push(arr[x1][i]); // 오른쪽 직사각형 고르기 y2는 고정, x1이 x2 직전까지 1씩 증가 for (let i = x1; i < x2; i++) stack.push(arr[i][y2]); // 아래쪽 직사각형 고르기 x2는 고정, y2가 y1 직전까지 1씩 감소 for (let i = y2; i > y1; i--) stack.push(arr[x2][i]); // 왼쪽 직사각형 고르기y1는 고정, x2가 x1 직전까지 1씩 감소 for (let i = x2; i > x1; i--) stack.push(arr[i][y1]); // 정답 찾기 answer.push(Math.min(...stack)); const temp = stack.pop(); stack.unshift(temp); for (let i = y1; i < y2; i++) arr[x1][i] = stack.shift(); for (let i = x1; i < x2; i++) arr[i][y2] = stack.shift(); for (let i = y2; i > y1; i--) arr[x2][i] = stack.shift(); for (let i = x2; i > x1; i--) arr[i][y1] = stack.shift(); } return answer; }
박노철
function solution(rows, columns, queries) { //행렬에서 직사각형 모양의 범위를 여러번 선택해서 테두리부분을 시계방향으로 한칸씩 회전 //(x1,y1, x2, y2)는 직사각형범위 x가 행, y가 렬 // 쿼리를 인덱스값에 매칭이 되도록 1씩 빼준다. const indexQueries=queries.map(query=>query.map(v=>v-1)); // 돌아야하는 board도 만들어준다. const board= Array.from({length:rows} ,(_,i)=>Array.from({length:columns}, (_,idx)=>(i*columns)+(idx+1))); const result =[]; for(let a of indexQueries){ // 어떻게 돌리냐?temp에 자기값을 넣고 앞에것을 땡겨온다. //돌면서 값을 넣어줄 numbers const numbers=new Set(); const [x1,y1, x2,y2]=a; // 우선 시작값을 넣어준다. let temp=[board[x1][y1]]; for(let i=y1+1; i<=y2; i++ ){ //앞에값을 빼오고 , 현재값은 넣어준다. const pre=temp.shift(); numbers.add(pre); temp.push(board[x1][i]); //현재 자리에 할당 board[x1][i]=pre; } for(let i=x1+1; i<=x2; i++){ const pre=temp.shift(); numbers.add(pre); temp.push(board[i][y2]); board[i][y2]=pre } for(let i=y2-1; i>=y1; i--){ const pre= temp.shift(); numbers.add(pre); temp.push(board[x2][i]); board[x2][i]=pre; } for(let i=x2-1; i>=x1; i--){ const pre=temp.shift(); numbers.add(pre); temp.push(board[i][y1]); board[i][y1]=pre; } result.push(Math.min(...numbers)) } return result }
이민희
function cycle(board, query) { const newBoard = board.map(row => [...row]); // 배열의 깊은복사 let [x1, y1, x2, y2] = query; x1--; y1--; x2--; y2--; let minValue = board[x1][y1]; // 초기화 for (let y = y1; y < y2; y++) { newBoard[x1][y + 1] = board[x1][y] if (board[x1][y] < minValue) minValue = board[x1][y] } for (let x = x1; x < x2; x++) { newBoard[x + 1][y2] = board[x][y2] if (board[x][y2] < minValue) minValue = board[x][y2] } for (let y = y2; y > y1; y--) { newBoard[x2][y - 1] = board[x2][y] if (board[x2][y] < minValue) minValue = board[x2][y] } for (let x = x2; x > x1; x--) { newBoard[x - 1][y1] = board[x][y1] if (board[x][y1] < minValue) minValue = board[x][y1] } return [newBoard, minValue]; // 회전 후의 행렬과 회전한 원소들 중 최소값을 반환 } function solution(rows, columns, queries) { // 초기 행렬 생성 let board = Array .from(Array(rows), () => new Array(columns).fill(0)) .map((row, rowIdx) => row.map((_, col) => rowIdx * columns + (col + 1) )) const result = []; queries.forEach((query) => { const [newBoard, minValue] = cycle(board, query); result.push(minValue); board = newBoard.map(row => [...row]); // 회전 후의 행렬로 재할당(배열의 깊은 복사)해줍니다. }); return result; }
박건우
function solution(rows, columns, queries) { const answer = []; const d = [[0, 1], [1, 0], [0, -1], [-1, 0]]; const board = new Array(rows + 1).fill() .map((_, i) => new Array(columns + 1).fill().map((_, j) => (i-1) * (columns) + j)); for(let [y1, x1, y2, x2] of queries){ let minValue = Infinity; const dequeue = []; const s = [[y1, x1], [y1, x2], [y2, x2], [y2, x1]]; let cnt = 0; // 시계로 돌면서 원소를 배열에 담아줍니다. for(let [dy, dx] of d){ let [ny, nx] = s[cnt]; let [ey, ex] = s[(cnt + 1) % 4]; while(ny !== ey || nx !== ex){ dequeue.push(board[ny][nx]); minValue = Math.min(minValue, board[ny][nx]); [ny, nx] = [ny + dy, nx + dx]; } cnt++; } // 끝에 있는 원소를 빼내고 앞에다가 넣어줍니다. dequeue.unshift(dequeue.pop()); cnt = 0; let idx = 0; // 다시 시계로 돌면서 배열의 원소를 넣어줍니다. for(let [dy, dx] of d){ let [ny, nx] = s[cnt]; let [ey, ex] = s[(cnt + 1) % 4]; while(ny !== ey || nx !== ex){ board[ny][nx] = dequeue[idx++]; [ny, nx] = [ny + dy, nx + dx]; } cnt++; } answer.push(minValue); } return answer; }
박주연
function solution(rows, columns, queries) { /* 접근 방법 1. 테두리를 4가지 방식으로 돌면서 min값 비교하여 넣기 2. min값 비교 -> 시계방향으로 회전시켜주기 -> 다음영역의 값 가지고있기 */ const answer = []; let board = Array.from({length: rows+1}, () => new Array(columns +1)); for(let i =1; i< rows+1 ; i++){ for(let j = 1; j < columns +1; j++){ board[i][j] = ((i-1)* columns + j ); } } queries.forEach(query => { let [startX, startY, endX, endY] = query; let min = rows * columns; // 최소값을 미리 초기화 let r = startX; let c = startY; //현재 값 let current = board[startX][startY]; let tmp = 0; // 왼쪽 -> 오른쪽 for(let i = startY; i < endY ; i++){ if(current < min) min = current; tmp = board[r][++c]; // 다음 영역의 값 저장 board[r][c] = current; // board 값 시계방향으로 옮기기 current = tmp; //다음 영역의 값을 current에 저장해서 다시 반복 } // 위 -> 아래 for(let i = startX; i < endX; i++){ if(current < min) min = current; tmp = board[++r][c]; board[r][c] = current; current = tmp; } // 오른쪽 -> 왼쪽 for(let i = startY; i < endY; i++){ if(current < min) min = current; tmp = board[r][--c]; board[r][c] = current; current = tmp; } // 아래 -> 위 for(let i = startX; i < endX; i++){ if(current < min) min = current; tmp = board[--r][c]; board[r][c] = current; current = tmp; } answer.push(min); }) return answer }