<프로그래머스 C++> 공원 산책 풀이

2026. 6. 4. 15:07Programmers

문제

O는 통로, X는 장애물, S는 시작점인 격자 공원에서 로봇 강아지가 명령에 따라 이동한다. 이동 중 공원을 벗어나거나 장애물을 만나면 해당 명령을 무시한다. 모든 명령 수행 후 위치를 [세로, 가로] 순으로 return하는 문제이다.

 


문제 핵심 파악

1. park에서 'S'의 위치를 찾아 시작점을 설정한다.

2. routes를 순회하면서 방향과 거리를 파싱한다.

3. 한 칸씩 이동하면서 매 칸마다 두 가지를 체크한다.

  • 공원 범위를 벗어났는가?
  • 장애물 'X'를 만났는가?

4. 두 조건 중 하나라도 해당되면 명령을 무시, 해당되지 않으면 그대로 진행한다.


문제 풀이

#include <string>
#include <vector>
using namespace std;

vector<int> solution(vector<string> park, vector<string> routes) {
    vector<int> answer;

    // 시작점 찾기
    for(int i = 0; i < park.size(); ++i)
    {
        int j = park[i].find('S');
        if(j != string::npos)
        {
            answer = {i, j};
            break;
        }
    }

    for(auto& route : routes)
    {
        int row = 0, col = 0;
        char dir = route[0];

        if(dir == 'N') row = -1;
        else if(dir == 'S') row = 1;
        else if(dir == 'E') col = 1;
        else if(dir == 'W') col = -1;

        bool valid = true;
        int r = answer[0], c = answer[1];

        for(int k = 0; k < stoi(route.substr(2)); ++k)
        {
            r += row;
            c += col;

            if(r < 0 || r >= park.size() || c < 0 || c >= park[0].size())
            {
                valid = false;
                break;
            }
            if(park[r][c] == 'X')
            {
                valid = false;
                break;
            }
        }
        if(valid)
            answer = {r, c};
    }
    return answer;
}

코드 흐름

1. 시작점 찾기

for(int i = 0; i < park.size(); ++i)
{
    int j = park[i].find('S');
    if(j != string::npos)
    {
        answer = {i, j};
        break;
    }
}

각 행에서 find('S')로 시작점을 찾는다.

 

string::npos (find로 찾지 못했을 때 반환)가 아니면 찾은 것이므로 {i, j}로 시작점을 설정하고 break한다.

 

2. 방향 파싱

char dir = route[0];

if(dir == 'N') row = -1;
else if(dir == 'S') row = 1;
else if(dir == 'E') col = 1;
else if(dir == 'W') col = -1;

"E 2"에서 route[0]이 방향, stoi(route.substr(2))가 거리이다. 방향별로 row / col 증감값을 설정한다.

 

좌표가 [세로, 가로] 기준이므로 N/S는 row, E/W는 col로 지정한다.

 

3. 이동 가능 여부 체크

for(int k = 0; k < stoi(route.substr(2)); ++k)
{
    r += row;
    c += col;

    if(r < 0 || r >= park.size() || c < 0 || c >= park[0].size())
    {
        valid = false;
        break;
    }
    if(park[r][c] == 'X')
    {
        valid = false;
        break;
    }
}

한 칸씩 이동하면서 매 칸마다 범위와 장애물을 체크한다.

 

중간에 하나라도 걸리면 valid = false로 명령 전체를 무시한다.

 

4. 위치 업데이트

if(valid)
    answer = {r, c};

모든 칸을 통과했을 때, 위치를 업데이트 해준다.


트러블슈팅

원인

for(int k = 0; k < route.size(); ++k)

이동 거리를 route.size()로 설정

route.size()는 "E 2" 문자열의 길이이다. 이동 거리가 아니라 문자열 길이만큼 돌게 되어 틀린 결과가 나왔다.
 
 

해결 방법

for(int k = 0; k < stoi(route.substr(2)); ++k)

문자열의 길이가 아닌 문자열 뒷 부분 "2" 부분의 값을 추출하고 int로 변경해서 제 값이 나오도록 했다.


핵심 포인트

 

  • find('S')와 string::npos로 시작점을 찾는다
  • 이동 가능 여부는 목적지가 아닌 경로 전체를 한 칸씩 체크해야 한다
  • 좌표가 [세로, 가로] 기준이므로 N/S → row, E/W → col을 변경한다