알고리즘/백준

[백준][C++] 14503: 로봇 청소기

KANTAM 2023. 12. 6. 12:33

문제

 

14503번: 로봇 청소기

첫째 줄에 방의 크기 $N$과 $M$이 입력된다. $(3 \le N, M \le 50)$  둘째 줄에 처음에 로봇 청소기가 있는 칸의 좌표 $(r, c)$와 처음에 로봇 청소기가 바라보는 방향 $d$가 입력된다. $d$가 $0$인 경우 북쪽

www.acmicpc.net

풀이

구현, 시뮬레이션 문제이다. 

 

  • 로봇 청소기가 후진하지 못할 때까지 while로 무한 루프를 돈다. 
  • 현재 위치의 상하좌우에 청소 가능한 칸이 있는지 확인한다. 북, 동, 남, 서 방향으로 이동할 때의 x, y의 위치 변화는 다음과 같다.
// 북, 동, 남, 서
int move_x[4] = { -1, 0, 1, 0 };
int move_y[4] = { 0, 1, 0, -1 };
  • 청소 가능한 칸이 있다면 반시계 방향으로 회전해야 하는데, 이 때는 위의 변화를 역으로 돌아야 한다.
// 반시계 방향으로 회전
d = (d + 3) % 4;
  • 청소 가능한 칸이 없다면 후진해야 한다. 현재 방향에서 후진한 위치는 다음과 같이 표현할 수 있다.
// 현재 방향에서 후진한 위치
int back_x = r - move_x[d];
int back_y = c - move_y[d];

코드

#include <iostream>

using namespace std;

int room[50][50];
// 북, 동, 남, 서
int move_x[4] = { -1, 0, 1, 0 };
int move_y[4] = { 0, 1, 0, -1 };

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int N, M;
    cin >> N >> M;

    int r, c, d;
    cin >> r >> c >> d;

    for (int i = 0; i < N; ++i)
    {
        for (int j = 0; j < M; ++j)
        {
            cin >> room[i][j];
        }
    }

    int answer = 0;
    while (true)
    {
        // 현재 칸이 청소하지 않은 칸인 경우 청소
        if (room[r][c] == 0)
        {
            room[r][c] = -1;
            answer++;
        }

        // 상하좌우로 청소 가능한 칸이 있는지 확인
        int flag = false;
        for (int i = 0; i < 4; ++i)
        {
            int next_x = r + move_x[i];
            int next_y = c + move_y[i];
            if (room[next_x][next_y] == 0)
            {
                flag = true;
                break;
            }
        }
        
        // 청소가능한 칸이 있다면
        if (flag)
        {
            // 반시계 방향으로 회전
            d = (d + 3) % 4;        
            int next_x = r + move_x[d];
            int next_y = c + move_y[d];
            if (room[next_x][next_y] == 0)
            {
                r = next_x;
                c = next_y;
            }
        }
        else
        {
            // 현재 방향에서 후진한 위치
            int back_x = r - move_x[d];
            int back_y = c - move_y[d];
            if (room[back_x][back_y] != 1)
            {
                r = back_x;
                c = back_y;
            }
            else
            {
                // 후진한 위치가 벽인 경우 청소 종료
                break;
            }
        }
    }

    cout << answer;

    return 0;
}