컴퓨터기본/문제풀이

[백준] 14503번: 로봇 청소기

차가운오미자 2021. 11. 25. 23:12

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

 

14503번: 로봇 청소기

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

www.acmicpc.net

 

문제 이해

그냥 단순 시뮬레이션이라고 생각하면 된다.

단계도 깔끔하게 넘버링해서 줘서 그대로만 코드로 바꿔주면 된다.

그래도 조금 헷갈리긴 하는데,

 

while문 안에서

  • 현재 위치를 청소한다

 

  • 지금 방향에서 왼쪽, 예를 들어 북쪽이면 서쪽, 서쪽이면 남쪽을 살핀다. 왼쪽으로 돌기를 4번 해준다.
    그 중에서 청소가 안된 곳이 있으면 거기로 이동해주고, for문에서 break한다.

 

  • 4번 다 돌았는데 다음 갈 곳을 못찾았다
    • 뒤로 물러난다. 방향이 북쪽이었으면 남쪽, 서쪽이었으면 동쪽을 살핀다.
    • 근데 이 곳이 벽이다 == 갈 수 없다 == 청소 종료, return한다
    • 아니면 그 후진한 칸으로 간다.

 

이것만 잘 구현하면 문제가 없다.

void Move_and_Clean(void) {
	int ny, nx;
	while (1) {
		// 1. 현재 위치를 청소한다.
		int flag = 0;
		if (map[ry][rx] == 0) {
			map[ry][rx] = CLEAN;
			cleaned++;
		}
		// 2.  왼쪽 방향부터 차례대로 인접한 칸을 탐색
		for (int i = 0; i < 4; i++){
			int dir = (rd - 1) >= 0 ? (rd - 1) : 3;
			ny = ry + dy[dir];
			nx = rx + dx[dir];
			if (map[ny][nx] == 0) {
				rd = dir;
				ry = ny, rx = nx;
				flag = 1;
				break;
			}
			// 왼쪽에 없었다. 
			rd = dir;
		}
		if (flag == 1) continue;
		// 네 방향 모두 청소가 된 경우 -> 후진
		ny = ry + dy[rev[rd]];
		nx = rx + dx[rev[rd]];
		if (map[ny][nx] == 1) return;
		ry = ny, rx = nx;
	}
}

 

작성 코드

#include <stdio.h>
#include <string.h>
#define MAXMN 50
#define CLEAN 9

int N, M;
int map[MAXMN + 2][MAXMN + 2];
int ry, rx, rd; // 로봇 위치
int cleaned;

int dy[] = {-1, 0, 1, 0}; // 북, 동, 남, 서
int dx[] = { 0, 1, 0, -1 };
int rev[] = { 2, 3, 0, 1 };
void Get_Input(void) {
	scanf("%d %d", &N, &M);
	scanf("%d %d %d", &ry, &rx, &rd);
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			scanf("%d", &map[i][j]);
		}
	}
}

void Move_and_Clean(void) {
	int ny, nx;
	while (1) {
		// 1. 현재 위치를 청소한다.
		int flag = 0;
		if (map[ry][rx] == 0) {
			map[ry][rx] = CLEAN;
			cleaned++;
		}
		// 2.  왼쪽 방향부터 차례대로 인접한 칸을 탐색
		for (int i = 0; i < 4; i++){
			int dir = (rd - 1) >= 0 ? (rd - 1) : 3;
			ny = ry + dy[dir];
			nx = rx + dx[dir];
			if (map[ny][nx] == 0) {
				rd = dir;
				ry = ny, rx = nx;
				flag = 1;
				break;
			}
			// 왼쪽에 없었다. 
			rd = dir;
		}
		if (flag == 1) continue;
		// 네 방향 모두 청소가 된 경우 -> 후진
		ny = ry + dy[rev[rd]];
		nx = rx + dx[rev[rd]];
		if (map[ny][nx] == 1) return;
		ry = ny, rx = nx;
	}
}

int main(void) {
	Get_Input();
	Move_and_Clean();
	printf("%d", cleaned);
	return 0;
}

 

'컴퓨터기본 > 문제풀이' 카테고리의 다른 글

[백준] 14501번: 퇴사  (0) 2021.11.25
[백준] 14502번: 연구소  (0) 2021.11.25
[백준] 14888번: 연산자 끼워넣기  (0) 2021.11.25
[백준] 14890번: 경사로  (0) 2021.11.24
[백준] 14891번: 톱니바퀴  (0) 2021.11.24