알고리즘 관련/BOJ
14503 로봇청소기
Andrew-Yun
2021. 1. 4. 22:20
단순한 구현문제이지만 구현 시간에 집중해야 하면 좋은 문제이다.
내가 생각한 구현 방법은 다음과 같다.
- 로봇청소기의 방향과 위치
- 로봇 청소기의 위치와 방향을 구조체로 묶어 한 번에 관리하여 편리하게끔 하였다.
- 로봇 청소기의 동작 순서
- 문제에 나와있는 로봇청소기의 동작 순서만 보면 A, B, C, D 순서대로 구현해야할 것 같지만, 사실 종료 조건이 포함되어 있기 때문에 유의하여 구현해야 한다.
- A조건 : 위치와 방향을 수정하며, 맨 마지막 순위로 둔다.
- B조건 : 위치만 수정하며, A조건 보다 먼저 확인한다.
- C조건 : 위치만 수정하며, B조건 보다 먼저 확인한다.
- D조건 : 이 조건을 만족할 때까지 반복문을 수행하며, 가장 먼저 확인한다.
- 문제에 나와있는 로봇청소기의 동작 순서만 보면 A, B, C, 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;
}