dev_beomgeun
꾸준하게 차근차근
dev_beomgeun
전체 방문자
오늘
어제
  • 분류 전체보기 (170)
    • 전공 (0)
      • 운영체제 (0)
      • 알고리즘 (0)
      • 자료구조 (0)
      • 데이터베이스 (0)
      • 네트워크 (0)
    • 개발 공부 (32)
      • 웹 (6)
      • 리눅스 (4)
      • 머신러닝 (1)
      • 스프링 (17)
      • Git (2)
      • AWS (2)
    • 개발 도서, 강의 (3)
      • 스프링 입문을 위한 자바 객체지향의 원리와 이해 (0)
      • 모든 개발자를 위한 HTTP 웹 기본 지식(김영한.. (2)
      • 스프링 부트와 AWS로 혼자 구현하는 웹서비스 (1)
    • 문제 풀이 (118)
      • 백준 알고리즘 (72)
      • 프로그래머스 알고리즘, SQL (38)
      • Hackerrank SQL (8)
    • 프로젝트 기록 (4)
      • 캡스톤 종합설계 (4)
      • 반려하루 프로젝트 (0)
    • 활동 기록 (12)
      • 네이버 부스트캠프 (7)
      • 취준 & 코테 (4)
      • 소프트웨어 마에스트로 13기 (1)
    • 이것저것 (1)

블로그 메뉴

  • 홈
  • 깃허브
  • 링크드인
  • 방명록

공지사항

인기 글

태그

  • 회고
  • 백준
  • HackerRank mysql
  • c++
  • 부스트캠프
  • 반성
  • 서블릿
  • dp
  • AI Tech
  • 기록
  • 프로그래머스
  • 백준 DP
  • 일기
  • 프로그래머스 SQL
  • Baekjoon
  • 스프링
  • BFS
  • Hackerrank
  • 그래프탐색
  • 네이버 부스트캠프

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
dev_beomgeun

꾸준하게 차근차근

문제 풀이/백준 알고리즘

[baekjoon 14503] 로봇 청소기 (구현, 시뮬레이션) (C++)

2021. 9. 24. 21:28
728x90

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

 

14503번: 로봇 청소기

로봇 청소기가 주어졌을 때, 청소하는 영역의 개수를 구하는 프로그램을 작성하시오. 로봇 청소기가 있는 장소는 N×M 크기의 직사각형으로 나타낼 수 있으며, 1×1크기의 정사각형 칸으로 나누어

www.acmicpc.net

로봇 청소기가 청소할 수 있는 영역의 개수를 구해야 한다.

일반 4방향 탐색이 아닌, 기본적으론 반시계 방향 탐색을 하며 여러 가지 규칙이 있다.

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

 

사실 구현, 시뮬레이션 문제는 규칙 따라 하라는 대로 하면 풀린다. 하지만 보통 규칙이 복잡해서 정리가 안된다.

나의 경우 규칙 2-3을 제대로 읽지 않아서 디버깅에 시간을 좀 썼다.

"네 방향 모두 청소가 이미 되어있거나 벽인 경우에는" 이란 키워드에 집중해서 후진도 저 케이스에는 못하는 걸로 생각했다. 하지만 후진은 벽이 아니면 가능하다!

또한, 2-1이 부합하면 회전 후 한 칸 전진이고, 2-2면 그냥 회전만 한다.

 

나머지 조건은 귀찮은 조건들이어서 차근차근 풀었다.

1번 조건은 그 영역을 청소한다 이므로 그냥 flag를 이용해서 cnt++만 해주었다.

그리고 2번 조건은 왼쪽 방향부터 차례차례 4방향을 봐야 하므로 for문을 이용해주었고

2-1 조건에 부합하면 for문을 벗어나 주었다.

2-2 조건에 부합하면 for문을 벗어나지 않고 다음 방향으로 회전만 하고 계속 진행.

2-3 조건에 부합하면 방향 따라 후진하고 후진 가능하면 후진, 아니면 종료했다.

 

#include <iostream>

using namespace std;

int n, m, room[51][51], r, c, d, check[51][51];
int moving[4][2] = { {-1, 0}, {0, 1}, {1, 0}, {0, -1}};

int searching(int startX, int startY, int dir) {
	int cnt = 0;
	int x = startX, y = startY, d = dir;
	int searchFlag = true;
	while (1) {
		if (searchFlag) { // 청소 가능하면 그 영역을 청소하고 영역을 센다.
			if (!check[x][y]) {
				cnt++;
				check[x][y] = true;
			}
		} // 아니면 바로 조건 2번(반시계 4방향 탐색 시작)
		searchFlag = false; // 조건 2-b, 2-c를 위해서 매번 초기화
		for (int i = 0; i < 4; i++) {
			int nd = (d + 3) % 4;
			int nx = x + moving[(d + 3) % 4][0];
			int ny = y + moving[(d + 3) % 4][1];
			if (nx >= 0 && nx < n && ny >= 0 && ny < m) {
				if (room[nx][ny] == 0 && !check[nx][ny]) {
					x = nx;
					y = ny;
					d = nd;
					searchFlag = true;
					break;
				} // 다시 1번으로(현재 위치 청소)
				else if (room[nx][ny] == 1 || check[nx][ny]) {
					check[nx][ny] = true;
					d = nd; // 방향만 갱신해준다.
					continue; // 다른 방향을 봐야하므로 for문을 벗어나지 않는다.
				}
			}
		}
		if (!searchFlag) { // 4방향 이미 청소되어 있다면 방향 그대로 후진
			x = x + moving[(d + 2) % 4][0];
			y = y + moving[(d + 2) % 4][1];
			if (x < 0 || y < 0 || x >= n || y >= m)
				return cnt;
			if (room[x][y] == 0) // 벽이 아니면 계속 진행
				continue;
			if (check[x][y]) // 벽 + 후진했는데 이미 청소한 곳이면 종료
				return cnt;
		}
	}
	return cnt;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin >> n >> m;
	cin >> r >> c >> d;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cin >> room[i][j];
		}
	}
	cout << searching(r, c, d);
}
728x90
저작자표시 비영리 변경금지 (새창열림)

'문제 풀이 > 백준 알고리즘' 카테고리의 다른 글

[baekjoon 22867] 종점 (스위핑, 문자열, 정렬) (C++)  (0) 2021.10.08
[baekjoon 22860] 폴더 정리(small) (DFS, BFS, 구현, HashMap) (C++)  (0) 2021.10.05
[baekjoon 14719] 빗물 (구현, 스택) (C++)  (0) 2021.09.24
[baekjoon 19951] 태상이의 훈련소 생활 (누적합) (C++)  (0) 2021.09.21
[baekjoon 3190] 뱀 (덱, 시뮬레이션) (C++)  (0) 2021.09.21
    '문제 풀이/백준 알고리즘' 카테고리의 다른 글
    • [baekjoon 22867] 종점 (스위핑, 문자열, 정렬) (C++)
    • [baekjoon 22860] 폴더 정리(small) (DFS, BFS, 구현, HashMap) (C++)
    • [baekjoon 14719] 빗물 (구현, 스택) (C++)
    • [baekjoon 19951] 태상이의 훈련소 생활 (누적합) (C++)
    dev_beomgeun
    dev_beomgeun
    백엔드 개발을 하며 얻은 지식과 경험을 공유합니다. 현재 카카오페이에서 백엔드 엔지니어로 일하고 있습니다.

    티스토리툴바