danbibibi
article thumbnail

1. 문제

문제 바로가기> BOJ 14503번: 로봇 청소기

 

14503번: 로봇 청소기

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

www.acmicpc.net

 

2. 풀이

문제에서 설명한 조건에 따라 구현해주면 된다!

문제의 2-1, 2-2 조건은 현재 위치에서 반 시계 방향으로 돌면서 청소 가능한 위치를 찾는 것을 의미한다!

[북 동 남 서] 순서의 배열이기 때문에, 반시계 방향은 -1을 해주면 된다.

이때, "북(0)-1 = -1" 이므로, 이를 방지하기 위해 "(d-1+4)%4 = (d+3)%4" 를 해준 것이다.

 

2.0.1. C++

<cpp />
#include<iostream> #include<queue> #define WALL 1 #define MAX 51 using namespace std; struct DATA { int y, x, dir; }; int N, M; int r, c, d; int map[MAX][MAX]; bool visited[MAX][MAX]; int dy[] = {-1, 0, 1, 0}; // 북 동 남 서 int dx[] = {0, 1, 0, -1}; void input(){ cin >> N >> M; cin >> r >> c >> d; for(int i=0; i<N; i++){ for(int j=0; j<M; j++) cin >> map[i][j]; } } void solution(){ queue<DATA> q; q.push({r, c, d}); visited[r][c] = true; int ans = 1; while(!q.empty()){ int y = q.front().y; int x = q.front().x; int dir = q.front().dir; q.pop(); bool flag = true; int left = dir; for(int i=0; i<4; i++){ left = (left+3)%4; // 반시계 방향 탐색 (2-1, 2-2) int ny = y+dy[left]; int nx = x+dx[left]; if(ny<0 || ny>=N || nx<0 || nx>=M) continue; // 범위를 벗어나는 경우 if(visited[ny][nx] || map[ny][nx]==WALL) continue; // 이미 청소한 경우, 벽인 경우 visited[ny][nx] = true; // 청소 q.push({ny, nx, left}); flag = false; ans++; break; } if(flag){ // 네 방향 모두 청소가 이미 되어있거나 벽인 경우 int back = (dir+2)%4; // 뒤쪽 int ny = y+dy[back]; int nx = x+dx[back]; if(ny<0 || ny>=N || nx<0 || nx>=M || map[ny][nx]==WALL) break; // 네 방향 모두 청소가 이미 되어있거나 벽이면서, 뒤쪽이 벽이라 후진도 할 수 없는 경우 q.push({ny, nx, dir}); // 후진 가능한 경우 } } cout << ans; } int main(){ ios_base::sync_with_stdio(0); cin.tie(0); input(); solution(); }

 

2.0.2. Java

<java />
import java.io.*; import java.util.*; public class Main { static final int WALL =1 ; static final int MAX =51 ; static class DATA{ int r, c, d; public DATA(int r, int c, int d) { super(); this.r = r; this.c = c; this.d = d; } } static int N, M, ans=0; static int r, c, d; static int map[][]; static boolean visited[][]; static int dy[] = {-1, 0, 1, 0}; // 북 동 남 서 static int dx[] = {0, 1, 0, -1}; public static void main(String[] args) throws Exception { // System.setIn(new FileInputStream("res/input.txt")); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); N = Integer.parseInt(st.nextToken()); M = Integer.parseInt(st.nextToken()); map = new int[N][M]; visited = new boolean[N][M]; st = new StringTokenizer(br.readLine()); r = Integer.parseInt(st.nextToken()); c = Integer.parseInt(st.nextToken()); d = Integer.parseInt(st.nextToken()); for(int i=0; i<N; i++){ st = new StringTokenizer(br.readLine()); for(int j=0; j<M; j++) { map[i][j] = Integer.parseInt(st.nextToken()); } } solution(); } private static void solution() { Deque<DATA> q = new ArrayDeque<>(); q.addLast(new DATA(r, c, d)); visited[r][c] = true; int ans = 1; while(!q.isEmpty()){ int y = q.peek().r; int x = q.peek().c; int dir = q.peek().d; q.poll(); boolean flag = true; int left = dir; for(int i=0; i<4; i++){ left = (left+3)%4; // 반시계 방향 탐색 (2-1, 2-2) int ny = y+dy[left]; int nx = x+dx[left]; if(ny<0 || ny>=N || nx<0 || nx>=M) continue; // 범위를 벗어나는 경우 if(visited[ny][nx] || map[ny][nx]==WALL) continue; // 이미 청소한 경우, 벽인 경우 visited[ny][nx] = true; // 청소 q.addLast(new DATA(ny, nx, left)); flag = false; ans++; break; } if(flag){ // 네 방향 모두 청소가 이미 되어있거나 벽인 경우 int back = (dir+2)%4; // 뒤쪽 int ny = y+dy[back]; int nx = x+dx[back]; if(ny<0 || ny>=N || nx<0 || nx>=M || map[ny][nx]==WALL) break; // 네 방향 모두 청소가 이미 되어있거나 벽이면서, 뒤쪽이 벽이라 후진도 할 수 없는 경우 q.addLast(new DATA(ny, nx, dir)); // 후진 가능한 경우 } } System.out.println(ans); } }

'문제 풀이 > SW 역량 테스트' 카테고리의 다른 글

BOJ 14502번: 연구소  (0) 2023.01.11
BOJ 14889번: 스타트와 링크  (0) 2023.01.11
BOJ 15686번: 치킨 배달  (0) 2023.01.10
BOJ 14888번: 연산자 끼워넣기  (0) 2023.01.09
BOJ 16236번: 아기상어  (0) 2022.12.26
profile

danbibibi

@danbibibi

꿈을 꾸는 시간은 멈춰 있는 것이 아냐 두려워하지 마 멈추지 마 푸른 꿈속으로