코딩 문제풀이

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

Emes 2022. 4. 2. 15:57

문제 내용

https://programmers.co.kr/learn/courses/30/lessons/77485

문제의 유형 및 풀이 방법

단순 구현 문제이다.

먼저 query에 해당하는 직사각형 범위 중에서 테두리 칸인지 확인한다.

bool IsBorder(int x, int y, const vector<int>& query)
{
    int x1 = query[IDX_X1];
    int y1 = query[IDX_Y1];
    int x2 = query[IDX_X2];
    int y2 = query[IDX_Y2];

    if (x1 == x || x2 == x || y1 == y || y2 == y)
    {
        return true;
    }
    else
    {
        return false;
    }
}

테두리칸이라면 시계 방향으로 한 칸 회전시키고, 회전시키면서 최솟값을 찾아낸다.

int RotateBorderAndGetMinVal(vector<vector<int>>& matrix, const vector<int>& query)
{    
    if (0 == matrix.size() || 4 != query.size())
    {
        return -1;
    }

    vector<vector<int>> tempMatrix = matrix;
    int minValue = MAX_INT;
    // 0을 기준으로 한 값
    int x1 = query[IDX_X1] - 1;
    int y1 = query[IDX_Y1] - 1;
    int x2 = query[IDX_X2] - 1;
    int y2 = query[IDX_Y2] - 1;

    for (int x = x1; x <= x2; x++)
    {     
        for (int y = y1; y <= y2; y++)
        {
            // 테두리 칸이 아니면 continue
            // x, y 는 현재 0부터 시작하는 index 기준으로 되어있으므로 +1 해준 것이다.
            if (false == IsBorder(x + 1, y + 1, query))
            {
                continue;
            }

            // 회전시키기
            // x1(위쪽)이고, y2보다 작으면 오른쪽 이동
            if (x1 == x && y2 > y)
            {
                matrix[x][y + 1] = tempMatrix[x][y];
            }
            // y2(오른쪽)이고, x2보다 작으면 아래쪽 이동
            else if (y2 == y && x2 > x)
            {
                matrix[x + 1][y] = tempMatrix[x][y];
            }
            // x2(아래쪽)이고, y1보다 크면 왼쪽 이동
            else if (x2 == x && y1 < y)
            {
                matrix[x][y - 1] = tempMatrix[x][y];
            }
            // y1(왼쪽)이고, x1보다 크면 위쪽 이동
            else if (y1 == y && x1 < x)
            {
                matrix[x - 1][y] = tempMatrix[x][y];
            }

            // 그리고 최솟값 업데이트
            if (minValue > tempMatrix[x][y])
            {
                minValue = tempMatrix[x][y];
            } 
        }
    }

    return minValue;
}

복습해야할 내용

  • queries에 들어있는 rows, columns는 index 1 부터 시작하므로, 구현할 때 이에 주의하자.

소스 코드

#include <string>
#include <vector>

using namespace std;

#define IDX_X1 0
#define IDX_Y1 1
#define IDX_X2 2
#define IDX_Y2 3
#define MAX_INT 10000

bool IsBorder(int x, int y, const vector<int>& query)
{
    int x1 = query[IDX_X1];
    int y1 = query[IDX_Y1];
    int x2 = query[IDX_X2];
    int y2 = query[IDX_Y2];

    if (x1 == x || x2 == x || y1 == y || y2 == y)
    {
        return true;
    }
    else
    {
        return false;
    }
}

int RotateBorderAndGetMinVal(vector<vector<int>>& matrix, const vector<int>& query)
{    
    if (0 == matrix.size() || 4 != query.size())
    {
        return -1;
    }

    vector<vector<int>> tempMatrix = matrix;
    int minValue = MAX_INT;
    // 0을 기준으로 한 값
    int x1 = query[IDX_X1] - 1;
    int y1 = query[IDX_Y1] - 1;
    int x2 = query[IDX_X2] - 1;
    int y2 = query[IDX_Y2] - 1;

    for (int x = x1; x <= x2; x++)
    {     
        for (int y = y1; y <= y2; y++)
        {
            // 테두리 칸이 아니면 continue
            // x, y 는 현재 0부터 시작하는 index 기준으로 되어있으므로 +1 해준 것이다.
            if (false == IsBorder(x + 1, y + 1, query))
            {
                continue;
            }

            // 회전시키기
            // x1(위쪽)이고, y2보다 작으면 오른쪽 이동
            if (x1 == x && y2 > y)
            {
                matrix[x][y + 1] = tempMatrix[x][y];
            }
            // y2(오른쪽)이고, x2보다 작으면 아래쪽 이동
            else if (y2 == y && x2 > x)
            {
                matrix[x + 1][y] = tempMatrix[x][y];
            }
            // x2(아래쪽)이고, y1보다 크면 왼쪽 이동
            else if (x2 == x && y1 < y)
            {
                matrix[x][y - 1] = tempMatrix[x][y];
            }
            // y1(왼쪽)이고, x1보다 크면 위쪽 이동
            else if (y1 == y && x1 < x)
            {
                matrix[x - 1][y] = tempMatrix[x][y];
            }

            // 그리고 최솟값 업데이트
            if (minValue > tempMatrix[x][y])
            {
                minValue = tempMatrix[x][y];
            } 
        }
    }

    return minValue;
}

vector<int> solution(int rows, int columns, vector<vector<int>> queries)
{
    vector<int> answer;

    vector<vector<int>> matrix;
    vector<int> tempVector;
    // 행렬 생성
    int cnt = 1;
    for (int i = 0; i < rows; i++)
    {
        tempVector.clear();
        for (int j = 0; j < columns; j++)
        {
            tempVector.push_back(cnt);
            cnt++;
        }
        matrix.push_back(tempVector);
    }

    // 최솟값 구하기
    for (int i = 0; i < queries.size(); i++)
    {
        vector<int>& query = queries[i];

        answer.push_back(
            RotateBorderAndGetMinVal(matrix, query)
        );    
    }

    return answer;
}