문제는 여기서 확인할 수 있다. BaekJoon #14503. 로봇 청소기
문제에서 주어진 작동 방식을 그대로 구현한다.
#define
하고 그 순서대로 mx[]
, my[]
를 만든다.check_range()
메소드를 만드는게 편하다.#define NORTH 0
#define WEST 1
#define SOUTH 2
#define EAST 3
int mx[] = {-1, 0, 1, 0};
int my[] = {0, 1, 0, -1};
bool check_range(int a, int b, int n, int m){
if(a<0 || b<0 || a>=n || b>=m) return false;
return true;
}
int left_dir(int d){
int left = d - 1;
if(left < 0) left += 4;
return left;
}
청소기의 움직임은 크게 두 쪼갈 낼 수 있다.
잘 쪼개두면 디버깅이 쉽다
cleaner cleaner_machine(x, y, d);
bool iscleaned = false;
bool isover = false;
int count_cleaned_floor = 0;
while(true){
iscleaned = cleaner_machine.clean(n, m);
isover = cleaner_machine.move(n, m);
if(iscleaned) count_cleaned_floor++;
if(!isover) break;
}
printf("%d", count_cleaned_floor);
bool clean()
현재 위치에서 청소할 수 있으면 칸을 CLEANED로 바꾸고 True를 리턴한다. 리턴값이 True인지 확인해서 청소한 칸을 카운트할 수 있다.
굳이 왜 이걸 나누냐면 청소는 못한 채 두, 세번은 왼쪽으로만 돌거나 후진하는 상황이 생기기 때문이다.
bool clean(int n, int m){
if(room[x][y] == NOT_CLEANED) {
room[x][y] = CLEANED;
return true;
}
else return false;
}
bool move()
현재 위치에서 회전 및 이동이 이루어지는 메소드다.
종료 조건을 만족하면 False를 리턴한다.
return false;
return true;
bool move(int n, int m){
// check_left
int left = left_dir(dir);
int nx = x + mx[left];
int ny = y + my[left];
if(is_not_cleaned(nx, ny, n, m)){
dir = left;
x = nx; y = ny;
return true;
}
else {
int turn_dir = left;
bool is_stucked = true;
// check four side
for(int i=0; i<3; i++){
turn_dir = left_dir(turn_dir);
if(is_not_cleaned(x + mx[turn_dir], y + my[turn_dir], n, m)){
is_stucked = false;
}
}
// all cleaned
if(is_stucked){
int back = left_dir(left);
int bx = x + mx[back];
int by = y + my[back];
if(!check_range(bx, by, n, m) || room[bx][by] == WALL){
// end condition
return false;
}
else { // go back
x = bx; y = by;
}
}
else { // just turn left
dir = left;
}
return true;
}
}