시뮬레이션이다.
* 방향에서 실수안하게 천천히 생각할 것
#include <iostream>
#define north 0
#define east 1
#define south 2
#define west 3
bool arr[51][51];
bool visited[51][51];
int sizeY, sizeX;
int posY, posX;
int direction; //0 ~ 3 북동남서(북쪽부터 시계방향)
int back[4][2] = { {1, 0}, {0, -1}, {-1, 0}, {0, 1} };
int left[4][2] = { {0, -1}, {-1, 0}, {0, 1}, {1, 0} };
int leftDirect[4] = {west, north, east, south};
int result = 0;
void clean(int y, int x, int cnt) {
if (!visited[y][x]) {
visited[y][x] = true;
result++;
}
posY = y;
posX = x;
if (cnt == 0) {
//4방향 모두 회전했을 때
int dy = y + back[direction][0];
int dx = x + back[direction][1];
if (0 <= dy && dy < sizeY && 0 <= dx && dx < sizeX) {
if (arr[dy][dx]) {
//4방향 및 뒤가 벽인경우
//printf("사방이 벽임 중단\n");
return;
}
else {
//4방향 청소 ok 및 뒤로 이동 가능한 경우
//printf("4방향 청소완료 후진\n");
clean(dy, dx, 4);
}
}
return;
}
int dy, dx;
dy = y + left[direction][0];
dx = x + left[direction][1];
//printf("현재좌표 %d,%d 방향:%d", y, x, direction);
//printf("왼쪽방향좌표 %d,%d\n", dy, dx);
//왼쪽이 벽이 아닐 때
if (0 <= dy && dy < sizeY && 0 <= dx && dx < sizeX) {
//왼쪽이 청소 가능할 때
if (!arr[dy][dx] && !visited[dy][dx]) {
direction = leftDirect[direction]; //방향을 왼쪽으로 틀고 전진
//printf("회전 후 방향 %d & 전진\n", direction);
clean(dy, dx, 4); //그쪽으로 이동 후 청소한다
}
//청소 불가능할 때
else {
direction = leftDirect[direction]; //방향을 그쪽으로 틀고
//printf("회전 후 방향 %d & 2번 루틴\n", direction);
clean(y, x, cnt - 1); //2번 루틴으로 돌아간다 == 같은 장소에서 머리만 꺽음
}
}
}
int main() {
scanf("%d %d", &sizeY, &sizeX);
scanf("%d %d %d", &posY, &posX, &direction);
for (int i = 0; i < sizeY; i++) {
for (int j = 0; j < sizeX; j++) {
int temp;
scanf("%d", &temp);
arr[i][j] = visited[i][j] = temp;
}
}
clean(posY, posX, 4);
printf("%d\n", result);
return 0;
}