본문 바로가기
코딩테스트 준비/프로그래머스

[프로그래머스][C++] 공원 산책

by 스테디코디스트 2023. 10. 27.
반응형

<문제 소개>


<소스 코드>

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

using namespace std;

vector<int> solution(vector<string> park, vector<string> routes) 
{
    vector<int> answer;
    map<vector<int>, bool> obstacles; // 장애물의 좌표들
    
    // 현재 위치 => {posX, posY}
    int posX, posY;
    
    // 시작 지점과 장애물 탐색
    for(int i = 0; i < park.size(); i++)
    {        
        for(int j = 0; j < park[i].size(); j++)
        {
            vector<int> v = {i, j}; // 탐색할 위치
            
            if(park[i][j] == 'S')
            {
                // 시작 위치 설정
                posX = i;
                posY = j;
            }
            else if(park[i][j] == 'X')
            {
                // 장애물인 경우
                obstacles[v] = true;
            }
        }
    }
    
    for(int i = 0; i < routes.size(); i++)
    {
        char dir = routes[i][0]; // 이동 방향
        int dist = routes[i][2] - '0'; // 이동 거리 -> 아스키코드 주의       
        
        // 임시 위치 => {tempX, tempY}
        int tempX = posX;
        int tempY = posY;        
        
        while(dist > 0)
        {            
            switch(dir)
            {
                case 'N': // 북                
                    tempX--;
                    break;
                case 'S': // 남
                    tempX++;
                    break;
                case 'W': // 서
                    tempY--;
                    break;
                case 'E': // 동
                    tempY++;
                    break;
            }
            
            // x좌표 또는 y좌표가 구간을 벗어난 경우 -> 이동x
            if(tempX >= park.size() || tempX < 0 ||
              tempY >= park[0].size() || tempY < 0) break;            
            
            // 장애물을 만난 경우 -> 이동x
            if(obstacles[{tempX,tempY}] == true) break;
                        
            // dist를 하나씩 감소시키면서 dist가 0이 될 때까지 한 칸씩 이동
            dist--;
        }
        
        if(dist == 0)
        {
            // 모든 이동을 무사히 끝낸 경우
            posX = tempX;
            posY = tempY;
        }
    }
        
    answer.push_back(posX);
    answer.push_back(posY);
    
    return answer;
}

<풀이과정>

1. 좌표를 입력받고 해당 좌표가 장애물이 맞는지 확인하는 컨테이너 map과 현재 위치를 나타내는 좌표 값들은 변수로 선언한다.

2. 입력값 park의 각 원소에 해당하는 문자열의 각 단어를 반복하며 시작 지점과 장애물을 찾아서 각각의 변수에 저장한다.

3. 이후 입력값 routes에 따라 이동을 수행하는데, 해당 입력 문자열의 0번째 단어가 이동 방향을 나타내고, 2번째 단어는 이동거리를 나타내므로 각각을 변수로 저장한다.

4. 이후 이동한 위치의 값이 유효한지를 판단하기 위해 기존 값은 보존하고, 임시로 값을 만들어 임시 값이 유효한 경우에만 기존 값에 이동한 위치가 들어있는 임시 값을 넣어주는 식으로 진행한다.

5. 이동은 매 이동마다 장애물을 만날 가능성이 있어 매 이동을 반복하며 예외사항을 판단한다.

6. 이동거리가 0이 될때까지 반복하며 이동방향에 따른 좌표의 변경값을 임시 값에 적용시킨다.

7. 이후 해당 임시 값이 구간을 벗어나는지 먼저 판단 후, 벗어난다면 반복을 종료시키고 벗어나지 않지만 장애물을 만난 경우를 앞서 장애물이 맞는지 판단하기 위해 선언한 맵 변수 obstacles를 이용해 판단 후 장애물을 만났다면 반복문을 종료시킨다.

8. 만약 위의 두 가지 모두에 해당되지 않는다면 이동거리 dist를 1씩 감소시켜 이동했음을 나타내고 다음 반복을 진행한다.

9. 이동을 위한 while 반복문이 종료되면 이동거리가 0인지 여부를 판단하여 중간에 예외사항에 걸려서 빠져나온 경우를 제외한 경우를 판단하고, 해당 경우에 기존 위치 값에 변경된 이동의 값을 넣었던 임시 값을 넣어 위치를 갱신해준다.

10. 모든 반복이 끝나 이동이 모두 종료된 이후 저장된 현재 위치값을 차례로 answer에 넣고 리턴해준다.


<코멘트>

좌표의 x,y가 동서남북으로 이동할 때 어떻게 이동하는지가 살짝 헷갈렸다.

그리고 각 문자열에서 각 단어는 char형인데 처음에는 아스키코드로 int로 바꿔주는 작업을 하지 않아서 헷갈렸다.


<제출결과>