본문 바로가기
전공공부/코딩테스트

(c++) 프로그래머스 "행렬 테두리 회전하기"

by 시아나 2022. 3. 7.

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

 

코딩테스트 연습 - 행렬 테두리 회전하기

6 6 [[2,2,5,4],[3,3,6,6],[5,1,6,3]] [8, 10, 25] 3 3 [[1,1,2,2],[1,2,2,3],[2,1,3,2],[2,2,3,3]] [1, 1, 5, 3]

programmers.co.kr


#include <string>
#include <vector>
#include <iostream>

using namespace std;

vector<int> solution(int rows, int columns, vector<vector<int>> queries) {
    vector<int> answer;
    int normal[101][101] = { 0 };
    int plus[4][2] = { {0,1},{1,0},{0,-1},{-1,0} };
    for (int i = 1; i <= rows; i++) {
        for (int k = 1; k <= columns; k++) {
            normal[i][k] = (i - 1) * columns + k;
        }
    }

    for (auto query : queries) {
        int h = query[2] - query[0]; //높이
        int w = query[3] - query[1]; //너비
        int x, y,tmp,minest;
        x = query[0]; y = query[1]; 
        tmp = normal[x][y];
        minest = tmp;
        for (int i = 0; i < 4; i++) {
            int top;
            if (i % 2 == 0)
                top = w;
            else
                top = h;
            for (int k = 0; k < top; k++) {
                x += plus[i][0]; y += plus[i][1];
                int num = normal[x][y];
                normal[x][y] = tmp;
                tmp = num;
                if (minest > tmp) minest = tmp;
            }
        }
        answer.push_back(minest);
    }

    return answer;
}

나는 빨간 사각형의 높이와 너비를 구해서 가능하면 for문을 적게 사용할 수 있도록 설계를 하였다.

차근차근 코드를 따라 해석해보겠다.


normal 배열은 행열을 저장할 배열이다.

plus 배열은 시계방향으로 돌기위한 방향을 의미한다.

int normal[101][101] = { 0 };
int plus[4][2] = { {0,1},{1,0},{0,-1},{-1,0} };
x+ 방향 -> y+ 방향 -> y- 방향 -> x-방향

먼저 회전하기 전의 행열을 저장할 것이다.

  for (int i = 1; i <= rows; i++) {
        for (int k = 1; k <= columns; k++) {
            normal[i][k] = (i - 1) * columns + k;
        }
    }

h는 높이이므로 x 값의 차이고 w는 너비이므로 y 값을 차로 잡았다.

x,y는 각각 현재 focus 잡고있는 배열의 x값과 y값을 저장할 것이다.

tmp는 이동시킬 값을 저장하고 minest는 이동하는 값중 가장 작은 값을 저장할 것이다.

        int h = query[2] - query[0]; //높이
        int w = query[3] - query[1]; //너비
        int x, y,tmp,minest;

처음에는 시작점을 focus한다. 

tmp와 minest에는 시작점의 값이 저장된다.

        x = query[0]; y = query[1]; 
        tmp = normal[x][y];
        minest = tmp;

다음에는 4번의 획이동을 할 것이다.

여기서 1,3은 w만큼 2,4는 h만큼 이동하기때문에 top라는 임시변수에 각각 w와 h를 넣는다.

            int top;
            if (i % 2 == 0)
                top = w;
            else
                top = h;

이제 top만큼 이동하면서 값을 시계방향으로 회전시킨다. 

            for (int k = 0; k < top; k++) {
                x += plus[i][0]; y += plus[i][1];
                int num = normal[x][y];
                normal[x][y] = tmp;
                tmp = num;
                if (minest > tmp) minest = tmp;
            }

tmp에는 a의 값이 저장되어있고 num에는 b의 값을 저장한다.

b의 자리에 tmp의 값을 넣고 다음 회전을 위해 num의 값을 tmp에 넣는다.

그리고 변경한 값 중 가장 작은 값을 찾기위해 if문을 실행한다.


answer.push_back(minest);

그리고 마지막으로 찾아낸 가장 작은값을 answer에 넣는다.