알고리즘 관련/BOJ

14503 로봇청소기

Andrew-Yun 2021. 1. 4. 22:20

단순한 구현문제이지만 구현 시간에 집중해야 하면 좋은 문제이다.

내가 생각한 구현 방법은 다음과 같다.

  1. 로봇청소기의 방향과 위치
    • 로봇 청소기의 위치와 방향을 구조체로 묶어 한 번에 관리하여 편리하게끔 하였다.
  2. 로봇 청소기의 동작 순서
    • 문제에 나와있는 로봇청소기의 동작 순서만 보면 A, B, C, D 순서대로 구현해야할 것 같지만, 사실 종료 조건이 포함되어 있기 때문에 유의하여 구현해야 한다.
      • A조건 : 위치와 방향을 수정하며, 맨 마지막 순위로 둔다.
      • B조건 : 위치만 수정하며, A조건 보다 먼저 확인한다.
      • C조건 : 위치만 수정하며, B조건 보다 먼저 확인한다.
      • D조건 : 이 조건을 만족할 때까지 반복문을 수행하며, 가장 먼저 확인한다.

정답코드

더보기
#include <iostream>
using namespace std;
int N, M;
int arr[50][50];
bool visit[50][50];
enum DIR {
	NORTH = 0,
	EAST,
	SOUTH,
	WEST
};
typedef struct Cleaner {
	int row;
	int col;
	int dir;
};
void setting()
{
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			arr[i][j] = 0;
		}
	}
	for (int i = 0; i < 50; i++) {
		for (int j = 0; j < 50; j++) {
			visit[i][j] = true;
		}
	}
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			visit[i][j] = false;
		}
	}
}
bool A(Cleaner& clr, int& cnt)
{
	Cleaner next = clr;
	if (clr.dir == DIR::NORTH &&
		visit[clr.row][clr.col - 1] == false) {
		next.col -= 1;
		next.dir = DIR::WEST;
	}
	else if (clr.dir == DIR::EAST &&
		visit[clr.row - 1][clr.col] == false) {
		next.row -= 1;
		next.dir = DIR::NORTH;
	}
	else if(clr.dir == DIR::SOUTH &&
		visit[clr.row][clr.col + 1] == false){
		next.col += 1;
		next.dir = DIR::EAST;
	}
	else if (clr.dir == DIR::WEST &&
		visit[clr.row + 1][clr.col] == false) {
		next.row += 1;
		next.dir = DIR::SOUTH;
	}
	else {
		//왼쪽 방향에 이미 청소한 칸임
		return false;
	}

	//왼쪽 방향 칸이 범위를 벗어남
	if (next.col < 0 || next.row < 0 ||
		next.row >= N || next.col >= M) {
		return false;
	}
	//왼쪽 방향 칸이 벽임
	else if (arr[next.row][next.col] == 1) {
		return false;
	}
	else {
		visit[next.row][next.col] = true;
		clr = next;
		cnt += 1;
		return true;
	}
}
bool B(Cleaner& clr)
{
	Cleaner next = clr;
	if (clr.dir == DIR::NORTH &&
		(visit[clr.row][clr.col - 1] == true ||
		arr[clr.row][clr.col - 1] == 1)) {
		next.dir = DIR::WEST;
	}
	else if (clr.dir == DIR::EAST &&
		(visit[clr.row - 1][clr.col] == true ||
		arr[clr.row - 1][clr.col] == 1)) {
		next.dir = DIR::NORTH;
	}
	else if (clr.dir == DIR::SOUTH &&
		(visit[clr.row][clr.col + 1] == true || 
		arr[clr.row][clr.col + 1] == 1)) {
		next.dir = DIR::EAST;
	}
	else if (clr.dir == DIR::WEST &&
		(visit[clr.row + 1][clr.col] == true ||
		arr[clr.row + 1][clr.col] == 1)) {
		next.dir = DIR::SOUTH;
	}
	else {
		return false;
	}
	clr = next;
	return true;
}
bool C(Cleaner& clr)
{
	Cleaner next = clr;
	if (
		(visit[clr.row - 1][clr.col] == true || arr[clr.row - 1][clr.col] == 1) &&
		(visit[clr.row + 1][clr.col] == true || arr[clr.row + 1][clr.col] == 1) &&
		(visit[clr.row][clr.col - 1] == true || arr[clr.row][clr.col - 1] == 1) &&
		(visit[clr.row][clr.col + 1] == true || arr[clr.row][clr.col + 1] == 1)
		)
	{
		if (next.dir == DIR::NORTH) {
			next.row += 1;
		}
		else if (next.dir == DIR::SOUTH) {
			next.row -= 1;
		}
		else if (next.dir == DIR::EAST) {
			next.col -= 1;
		}
		else if (next.dir == DIR::WEST) {
			next.col += 1;
		}
		clr = next;
		return true;
	}

	return false;
}
bool D(Cleaner& clr)
{
	if (
		(visit[clr.row - 1][clr.col] == true || arr[clr.row - 1][clr.col] == 1) &&
		(visit[clr.row + 1][clr.col] == true || arr[clr.row + 1][clr.col] == 1) &&
		(visit[clr.row][clr.col - 1] == true || arr[clr.row][clr.col - 1] == 1) &&
		(visit[clr.row][clr.col + 1] == true || arr[clr.row][clr.col + 1] == 1)
		)
	{
		if (clr.dir == DIR::NORTH && arr[clr.row + 1][clr.col] == 1) {
			return true;
		}
		else if (clr.dir == DIR::SOUTH && arr[clr.row - 1][clr.col] == 1) {
			return true;
		}
		else if (clr.dir == DIR::EAST && arr[clr.row][clr.col - 1] == 1) {
			return true;
		}
		else if (clr.dir == DIR::WEST && arr[clr.row][clr.col + 1] == 1) {
			return true;
		}
	}
	return false;
}
void sim(Cleaner& clr)
{
	int cnt = 0;
	//현재 위치 청소
	visit[clr.row][clr.col] = true;
	cnt++;
	while (1) {
		if (D(clr)) {
			break;
		}
		if (C(clr)) {
			continue;
		}
		if (B(clr)) {
			continue;
		}
		if (A(clr, cnt)) {
			continue;
		}
	}
	printf("%d\n", cnt);
}
int main()
{
	Cleaner clr;
	cin >> N >> M;
	cin >> clr.row >> clr.col >> clr.dir;
	setting();
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			cin >> arr[i][j];
		}
	}
	sim(clr);
	return 0;
}