알고리즘/백준
[백준][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;
}