오늘의 알고리즘

[C++]위클리 챌린지 아이템 줍기(프로그래머스 3레벨)

하늘하늘 . 2022. 4. 16. 18:22
#include <string>
#include <vector>
#include <queue>
using namespace std;
 
// 위, 아래, 오른쪽, 왼쪽 계산용도
int dy[] = { 0, 0, 1, -1 };
int dx[] = { 1, -1, 0, 0 };
 
int solution(vector<vector<int>> rectangle, int characterX, int characterY, int itemX, int itemY)
{
    // 좌표를 모두 2배 ( 이런 형식으로 )
    //  1 1      1 1 1
    //  1 1  ->  0 0 1
    //           1 1 1
    characterX *= 2;
    characterY *= 2;
    itemX *= 2;
    itemY *= 2;
 
    vector<vector<int>> vecRec(101, vector<int>(101, 0));
 
    // 직사각형의 시작점과 끝점
    int iXFirst = 0;
    int iXSecond = 0;
    int iYFirst = 0;
    int iYSecond = 0;
 
    for (int i = 0; i < rectangle.size(); ++i)
    {
        for (int j = 0; j < rectangle[0].size(); ++j)
        {
            // 내부 크기도 *2
            rectangle[i][j] *= 2;
        }
 
        iXFirst = rectangle[i][0];
        iYFirst = rectangle[i][1];
        iXSecond = rectangle[i][2];
        iYSecond = rectangle[i][3];
 
        for (int z = iYFirst; z <= iYSecond; ++z)
        {
            for (int k = iXFirst; k <= iXSecond; ++k)
            {
                vecRec[z][k] = 1;
            }
        }
    }
 
    // 직사각형의 내부 모두 0
    for (int i = 0; i < rectangle.size(); ++i)
    {
        iXFirst = rectangle[i][0];
        iYFirst = rectangle[i][1];
        iXSecond = rectangle[i][2];
        iYSecond = rectangle[i][3];
 
        for (int j = iYFirst + 1; j < iYSecond; ++j)
        {
            for (int z = iXFirst + 1; z < iXSecond; ++z)
            {
                vecRec[j][z] = 0;
            }
        }
    }
 
    // BFS
    queue<pair<int, int>> que = {};
    que.emplace(characterX,characterY);
 
    while (!que.empty())
    {
        int iX = que.front().first;
        int iY = que.front().second;
        que.pop();
 
        if (iX == itemX && iY == itemY)
            break;
 
        for (int i = 0; i < 4; ++i)
        {
            int iNextY = iY + dy[i];
            int iNextX = iX + dx[i];
 
            // 계산하지 않은 것만 1로
            if (vecRec[iNextY][iNextX] == 1)
            {
                que.emplace(iNextX, iNextY);
 
                // DP처럼 계산해나가면서 입력
                vecRec[iNextY][iNextX] = vecRec[iY][iX] + 1;
            }
        }
    }
 
    return  vecRec[itemY][itemX] * 0.5;
}
 

1.*2 한다는 생각을 하지 못했다.

2. BFS인거는 생각했는데 직사각형 내부를 어떻게 지우지...? 라는 생각만 가득했다

 

이걸 생각해내는 게 이 문제의 핵심이었는 듯