재귀함수의 return 시점을 생각하느라 까다로웠다.
빈 공간을 청소한 후, 4 방향을 검사한다.
차례대로 검사하는데 빈칸이 나오면 청소하고 남은 나머지 방향은 검사 할 필요가 없다.
조건대로 청소했거나 벽이라면 그 방향으로 방향을 바꿔주고 계속 방향을 검사한다.
네 방향을 검사했는데도 청소할 구역을 발견하지 못했으면
바라보는 방향을 유지하고 한칸 후진하고 다시 clean 함수를 진행하는데 후진할 공간이 벽이면 종료한다.
//백준 로봇청소기
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
struct robot {
int rx;
int ry;
int d; //0:북 1:동 2:남 3:서
int room;
};
int N, M;
robot rb;
int map[50][50]; //0->빈칸 1->벽 2->청소함
int dir[4][2] = { {0,-1},{-1,0},{0,1},{1,0} }; //0->북의 왼방, 1->동의 왼방 2->남의 왼방 3->서의 왼방
int bacK_dir[4][2] = { {1,0},{0,-1},{-1,0},{0,1} }; //북,동,남,서의 후진 방향
void Clean(int x, int y) {
if (map[x][y] == 0) {
rb.room++;
map[x][y] = 2;
}
//네 방향 검사
for (int i = 0; i < 4; i++) {
int next_dir = 0;
//북(0)->서(3), 동(1)->북(0), 남(2)->동(1), 서(3)->남(2)
if (rb.d == 0) {
next_dir = 3;
}
else {
next_dir = rb.d - 1;
}
int nx = x + dir[rb.d][0];
int ny = y + dir[rb.d][1];
//빈칸이면 청소, 청소했다면 더이상 나머지 방향을 검사할 필요 없음
if (map[nx][ny] == 0) {
rb.d = next_dir;
Clean(nx, ny);
return;
}
//청소했거나 벽이면 방향을 바꿔줌
if (map[nx][ny] == 2 || map[nx][ny] == 1) {
rb.d = next_dir;
}
}
//네 방향 검사 끝
//네 방향 모두 청소가 되어있거나 벽이면 바라보는 방향을 유지하고 한칸 후진
//후진할 공간이 벽이면 종료
int back_x = x + bacK_dir[rb.d][0];
int back_y = y + bacK_dir[rb.d][1];
if (map[back_x][back_y] == 1) {
return;
}
else {
Clean(back_x, back_y);
return;
}
}
int main() {
scanf("%d %d", &N, &M);
scanf("%d %d %d", &rb.rx, &rb.ry, &rb.d);
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
scanf("%d", &map[i][j]);
}
}
rb.room = 0;
Clean(rb.rx, rb.ry);
cout << rb.room << '\n';
return 0;
}