문제 내용
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;
}
'코딩 문제풀이' 카테고리의 다른 글
[프로그래머스] 순위 검색 (0) | 2022.04.03 |
---|---|
[프로그래머스] k진수에서 소수 개수 구하기 (0) | 2022.03.27 |
[백준] 연산자 끼워넣기 - 14888 (0) | 2021.04.30 |
[백준] 이진수 - 3460 (0) | 2021.04.29 |
[백준] 약수 구하기 - 2501 (0) | 2021.04.29 |