danbibibi
article thumbnail

문제

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

 

14503번: 로봇 청소기

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

www.acmicpc.net

 

풀이

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

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

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

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

 

C++

#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();
}

 

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

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