-
백준 14503번 로봇 청소기 :: 마이구미알고리즘 풀이/그래프 2017. 10. 28. 17:34반응형
이 글은 백준 알고리즘 문제 14503번 "로봇 청소기" 를 풀이한다.
삼성 SW 역량 테스트 문제 중 하나의 문제이다.
본인은 BFS를 활용한 풀이를 설명할 것이다.
문제 링크 - https://www.acmicpc.net/problem/14503
BFS 이해 - http://mygumi.tistory.com/102
로봇 청소기가 주어졌을 때, 청소하는 영역의 개수를 구하는 프로그램을 작성하시오.
로봇 청소기가 있는 장소는 N×M 크기의 직사각형으로 나타낼 수 있으며, 1×1크기의 정사각형 칸으로 나누어져 있다. 각각의 칸은 벽 또는 빈 칸이다. 청소기는 바라보는 방향이 있으며, 이 방향은 동, 서, 남, 북중 하나이다. 지도의 각 칸은 (r, c)로 나타낼 수 있고, r은 북쪽으로부터 떨어진 칸의 개수, c는 서쪽으로 부터 떨어진 칸의 개수이다.
로봇 청소기는 다음과 같이 작동한다.
- 현재 위치를 청소한다.
- 현재 위치에서 현재 방향을 기준으로 왼쪽방향부터 차례대로 탐색을 진행한다.
- 왼쪽 방향에 아직 청소하지 않은 공간이 존재한다면, 그 방향으로 회전한 다음 한 칸을 전진하고 1번부터 진행한다.
- 왼쪽 방향에 청소할 방향이 없다면, 그 방향으로 회전하고 2번으로 돌아간다.
- 네 방향 모두 청소가 이미 되어있거나 벽인 경우에는, 바라보는 방향을 유지한 채로 한 칸 후진을 하고 2번으로 돌아간다.
- 네 방향 모두 청소가 이미 되어있거나 벽이면서, 뒤쪽 방향이 벽이라 후진도 할 수 없는 경우에는 작동을 멈춘다.
로봇 청소기는 이미 청소되어있는 칸을 또 청소하지 않으며, 벽을 통과할 수 없다.
BFS를 응용하여 로봇이 작동 순서 그대로 이동하는 것을 구현했다.
로봇은 항상 왼쪽 방향만으로만 이동한다는 것을 활용해야한다.
그래서 코드를 보면, 큐의 사이즈는 항상 1 이하일 것이다.
BFS 특성을 활용해 4번의 작동은 큐가 비었다는 것을 의미하기에, 신경쓰지 않았다.
작동 순서에 따른 회전과 후진을 위한 방향만을 잘 지정해주면 문제는 쉽게 해결된다.
작동 순서 그대로를 구현했기 때문에, 설명보다는 코드를 통해 이해하면 된다.
Github - https://github.com/hotehrud/acmicpc/tree/master/graph
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112static int[][] map = new int[50][50];static int[] dx = { 0, 1, 0, -1 }; // 북 동 남 서static int[] dy = { -1, 0, 1, 0 };static boolean[][] visited = new boolean[50][50];static Robot start;static int m, n, ans;private void solve() {m = sc.nextInt();n = sc.nextInt();int s = sc.nextInt();int e = sc.nextInt();int d = sc.nextInt();for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {map[i][j] = sc.nextInt();}}start = new Robot(s, e, d);visited[s][e] = true;bfs();System.out.println(ans + 1);}public static void bfs() {Queue<Robot> q = new LinkedList<>();q.add(start);while (!q.isEmpty()) {Robot pos = q.poll();int d = pos.d;int y = pos.r;int x = pos.c;int nextDirection = d;int nx = 0;int ny = 0;boolean flag = false;// 왼쪽 방향에 청소하지 않은 구역 탐색for (int i = 0; i < 4; i++) {nextDirection = turnDirection(nextDirection);nx = dx[nextDirection] + x;ny = dy[nextDirection] + y;if (0 <= nx && nx < n && 0 <= ny && ny < m) {if (map[ny][nx] == 0 && !visited[ny][nx]) {visited[ny][nx] = true;++ans;q.add(new Robot(ny, nx, nextDirection));flag = true;break;}}}// 후진if (!flag) {nextDirection = backDirection(d);nx = dx[nextDirection] + x;ny = dy[nextDirection] + y;if (0 <= nx && nx < n && 0 <= ny && ny < m) {if (map[ny][nx] == 0) {q.add(new Robot(ny, nx, d));}}}}}public static int backDirection(int d) {if (d == 0) {return 2;} else if (d == 1) {return 3;} else if (d == 2) {return 0;} else {return 1;}}public static int turnDirection(int d) {// 0 북, 1 동, 2 남, 3 서if (d == 0) {return 3;} else if (d == 1) {return 0;} else if (d == 2) {return 1;} else {return 2;}}public static class Robot {int r;int c;int d;Robot(int r, int c, int d) {this.r = r;this.c = c;this.d = d;}}cs 반응형'알고리즘 풀이 > 그래프' 카테고리의 다른 글
백준 14888번 연산자 끼워넣기 :: 마이구미 (0) 2017.10.29 백준 1726번 로봇 :: 마이구미 (0) 2017.10.28 백준 9518번 로마 카톨릭 미사 :: 마이구미 (0) 2017.10.15 백준 3055번 탈출 :: 마이구미 (8) 2017.10.15 백준 2251번 물통 :: 마이구미 (0) 2017.10.03