study
행렬 테두리 회전하기[프로그래머스]
Date: 2026-05-26 22:59
Update: 2026-05-26 23:10


행렬 테두리 회전하기[프로그래머스]

접근법:

  1. 숫자가 채워진 보드를 만든다.
  2. 회전을 시킨다.
  3. 회전하면서 최솟값을 기록한다.
    1. 현재 인덱스의 위치에 따라서 어느방향으로 갈지 정한다
      1. 첫번쨰 열이라면 y값을 증가
      2. 첫번째 행이라면 x값을 증가
      3. 두번째 열이라면 y값을 감소
      4. 두번째 행이라면 x값을 감소
      5. 시작점으로 돌아왔다면 값을 채워 넣고 함수를 끝낸다.
  4. 최솟값을 저장한다.
  5. 모든 회전이 끝난뒤 최솟값들을 리턴한다.
#include <string>
#include <vector>
#include <iostream>
using namespace std;
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};

void Rotate(int dir, int value, int cx, int cy, int x1, int y1, int x2, int y2, vector<vector<int>>& board, int& minValue)
{
    int nx = cx + dx[dir];
    int ny = cy + dy[dir];
    if(nx == x1 - 1 && ny == y1 - 1){
        board[nx][ny] = value; 
        minValue = min(minValue, value);
        return;
    }
    if(nx >= x2 || nx < x1 - 1 || ny >= y2 || ny < y1 - 1) return;
    int storeValue = board[nx][ny];
    board[nx][ny] = value;
    minValue = min(minValue, value);
    //첫번째 열 y증가
    if(nx == x1 - 1) Rotate(3, storeValue, nx, ny, x1, y1, x2, y2, board, minValue);
    //첫번째 행 x증가
    if(ny == y2 - 1) Rotate(1, storeValue, nx, ny, x1, y1, x2, y2, board, minValue);
    //두번째 열 y감소
    if(nx == x2 - 1) Rotate(2, storeValue, nx, ny, x1, y1, x2, y2, board, minValue);
    //두번째 행 x감소
    if(ny == y1 - 1) Rotate(0, storeValue, nx, ny, x1, y1, x2, y2, board, minValue);
}

vector<int> solution(int rows, int columns, vector<vector<int>> queries) {
    vector<int> answer;
    vector<vector<int>> board(rows, vector<int>(columns));
    
    for(int i = 0; i < rows; ++i)
    {
        for(int j = 0; j < columns; ++j)
        {
            board[i][j] = i * columns + j + 1;
        }
    }
    
    int dir = 0;
    for(auto& q : queries)
    {
        int minValue = 1e9;
        Rotate(3, board[q[0]-1][q[1]-1], q[0] -1, q[1] -1, q[0], q[1], q[2], q[3], board, minValue);
        answer.push_back(minValue);
    }
    return answer;
}

접근법:

  1. 숫자가 채워진 보드를 만든다.
  2. 각 회전 쿼리에 대한 회전을 진행한다.
    1. 인덱스 조절
    2. 시작점의 값을 임시변수에 저장(빈공간으로 취급)
    3. 이 빈공간을 채우는 방식으로 한칸씩 당겨온다(문제 설명과 다른 역방향)
      1. 왼쪽 테두리: 아래에 있는 값을 한 칸씩 당겨오고 최솟값을 갱신
      2. 아래쪽 테두리: 오른쪽에 있는값을 한칸씩 당겨오고 최솟값을 갱신
      3. 오른쪽 테두리: 위에 있는 값을 아래로 한칸씩 당겨오고 최솟값을 갱신
      4. 위쪽 테두리: 왼쪽에 있는값을 오른쪽으로 한칸씩 당겨오고 최솟값을 갱신한다.
      5. 처음에 빼두었던 임시값을 시작점의 바로 오른쪽에 넣는다.
    4. 최솟값을 저장한다.
  3. 최솟값을 담은 배열을 리턴한다.
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

vector<int> solution(int rows, int columns, vector<vector<int>> queries) {
    vector<int> answer;
    vector<vector<int>> board(rows, vector<int>(columns));
    
    // 초기 보드 세팅
    for(int i = 0; i < rows; ++i) {
        for(int j = 0; j < columns; ++j) {
            board[i][j] = i * columns + j + 1;
        }
    }
    
    // 각 쿼리에 대해 회전 수행
    for(auto& q : queries) {
        // 인덱스를 0부터 시작하도록 맞춤
        int x1 = q[0] - 1; int y1 = q[1] - 1;
        int x2 = q[2] - 1; int y2 = q[3] - 1;
        
        // 시작점의 값을 임시 저장 (이 자리는 비게 됨)
        int temp = board[x1][y1];
        int min_val = temp;
        
        // 1. 왼쪽 테두리 (위로 당기기)
        for(int i = x1; i < x2; ++i) {
            board[i][y1] = board[i + 1][y1];
            min_val = min(min_val, board[i][y1]);
        }
        // 2. 아래쪽 테두리 (왼쪽으로 당기기)
        for(int i = y1; i < y2; ++i) {
            board[x2][i] = board[x2][i + 1];
            min_val = min(min_val, board[x2][i]);
        }
        // 3. 오른쪽 테두리 (아래로 당기기)
        for(int i = x2; i > x1; --i) {
            board[i][y2] = board[i - 1][y2];
            min_val = min(min_val, board[i][y2]);
        }
        // 4. 위쪽 테두리 (오른쪽으로 당기기)
        for(int i = y2; i > y1 + 1; --i) { // 마지막 칸(y1)은 temp가 들어가야 하므로 y1+1까지만
            board[x1][i] = board[x1][i - 1];
            min_val = min(min_val, board[x1][i]);
        }
        
        // 비워두었던 자리에 처음 저장해둔 임시 값을 삽입
        board[x1][y1 + 1] = temp;
        
        // 최솟값을 정답에 추가
        answer.push_back(min_val);
    }
    
    return answer;
}