[BOJ] 14503번 로봇 청소기 c++

chowisely·2020년 9월 24일
0

BOJ

목록 보기
26/70

https://www.acmicpc.net/problem/14503

문제
로봇 청소기가 주어졌을 때, 청소하는 영역의 개수를 구하는 프로그램을 작성하시오. 로봇 청소기가 있는 장소는 N×M 크기의 직사각형으로 나타낼 수 있으며, 1×1크기의 정사각형 칸으로 나누어져 있다. 각각의 칸은 벽 또는 빈 칸이다. 청소기는 바라보는 방향이 있으며, 이 방향은 동, 서, 남, 북중 하나이다. 지도의 각 칸은 (r, c)로 나타낼 수 있고, r은 북쪽으로부터 떨어진 칸의 개수, c는 서쪽으로 부터 떨어진 칸의 개수이다.

로봇 청소기는 다음과 같이 작동한다.

  • 현재 위치를 청소한다.
  • 현재 위치에서 현재 방향을 기준으로 왼쪽방향부터 차례대로 탐색을 진행한다.
    • 왼쪽 방향에 아직 청소하지 않은 공간이 존재한다면, 그 방향으로 회전한 다음 한 칸을 전진하고 1번부터 진행한다.
    • 왼쪽 방향에 청소할 공간이 없다면, 그 방향으로 회전하고 2번으로 돌아간다.
    • 네 방향 모두 청소가 이미 되어있거나 벽인 경우에는, 바라보는 방향을 유지한 채로 한 칸 후진을 하고 2번으로 돌아간다.
    • 네 방향 모두 청소가 이미 되어있거나 벽이면서, 뒤쪽 방향이 벽이라 후진도 할 수 없는 경우에는 작동을 멈춘다.

로봇 청소기는 이미 청소되어있는 칸을 또 청소하지 않으며, 벽을 통과할 수 없다.


입력 1
3 3
1 1 0
1 1 1
1 0 1
1 1 1

출력 1
1


입력 2
11 10
7 4 0
1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0 0 1
1 0 0 0 1 1 1 1 0 1
1 0 0 1 1 0 0 0 0 1
1 0 1 1 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 1 0 1
1 0 0 0 0 0 1 1 0 1
1 0 0 0 0 0 1 1 0 1
1 0 0 0 0 0 0 0 0 1
1 1 1 1 1 1 1 1 1 1

출력 2
57

#include <iostream>
#include <cstdio>
#include <string.h>

using namespace std;

int N, M;
int r, c, d;
int nr, nc;
int arr[50][50] = {0,};
bool movable[4] = {true, true, true, true};

int leftr[4] = {0, -1, 0, 1};
int leftc[4] = {-1, 0, 1, 0};

int backr[4] = {1, 0, -1, 0};
int backc[4] = {0, -1, 0, 1};

int clean(int nr, int nc) {
  memset(movable, true, sizeof(movable) / sizeof(bool));
  r = nr;
  c = nc;
  arr[nr][nc] = -1;
  return 1;
}

int search() {
  int cnt = 0;
  if(arr[r][c] == 0) {
    arr[r][c] = -1;
    cnt += 1;
  }

  while(true) {
    switch(d) {
      case 0:
      case 1:
      case 2:
      case 3:
        nr = r + leftr[d];
        nc = c + leftc[d];
        if(nr > -1 && nr < N && nc > -1 && nc < M) {
          if(arr[nr][nc] == 0) {
            cnt += clean(nr, nc);
            movable[d] = true;
          }
          else {
            movable[d] = false;
          }
          d = d - 1 >= 0 ? d - 1 : 3;
        }
    }

    if(!movable[0] && !movable[1] && !movable[2] && !movable[3]) {
      nr = r + backr[d];
      nc = c + backc[d];
      if(nr > -1 && nr < N && nc > -1 && nc < M && arr[nr][nc] != 1) {
        r = nr;
        c = nc;
        memset(movable, true, sizeof(movable) / sizeof(bool));
      }
      else {
        break;
      }
    }
  }
  
  return cnt;
}

int main() {
  scanf("%d %d", &N, &M);
  scanf("%d %d %d", &r, &c, &d);
  for(int i = 0; i < N; i++) {
    for(int j = 0; j < M; j++) {
      scanf("%d", &arr[i][j]);
    }
  }
  printf("%d\n", search());
}

0개의 댓글