시뮬레이션이다.

 

* 방향에서 실수안하게 천천히 생각할 것

 

 

 

 

#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;
}

+ Recent posts