STUDY/Algorithm

[백준] 14503 로봇 청소기 python, C

sinawi95 2021. 7. 13. 22:06
728x90

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

 

14503번: 로봇 청소기

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

www.acmicpc.net

import sys; input=sys.stdin.readline
N, M = map(int, input().split())
r, c, d = map(int, input().split())
room = [list(map(int, input().split())) for _ in range(N)]
clean = [[0 for _ in range(M)] for _ in range(N)]
direction = [(-1, 0), (0, 1), (1, 0), (0, -1)]

answer = 0

while True:
    # 1 현재 위치 청소
    if not clean[r][c]:
        clean[r][c] = 1
        answer += 1

    # 2 현재 위치에서 현재 방향을 기준으로 왼쪽방향부터 차례로 탐색
    break_chk = False
    for ddir in range(1, 5):
        tmp = direction[(d - ddir) % 4]
        # a 왼쪽 방향에 아직 청소하지 않은 공간이 존재하면 그 방향으로 회전한 다음 한칸 전진 후 1번으로 돌아감
        # b 왼쪽 방향에 청소할 공간이 없다면 그방향으로 회전하고 2번으로 돌아감
        if 0 <= r + tmp[0] < N and 0 <= c + tmp[1] < M:
            if not clean[r + tmp[0]][c + tmp[1]] and not room[r + tmp[0]][c + tmp[1]]:
                r += tmp[0]
                c += tmp[1]
                d = (d - ddir) % 4
                break_chk = True
                break
    else:
        # 네방향 모두 이미 청소가 되어있거나 벽인 경우
        tmp = direction[d]
        if 0 <= r - tmp[0] < N and 0 <= c - tmp[1] < M:
            # 뒤쪽 방향도 벽인경우
            if room[r - tmp[0]][c - tmp[1]]:
                break
            #  바라보는 방향을 유지한채로 한칸 후진후 2번으로 돌아감
            r -= tmp[0]
            c -= tmp[1]
print(answer)

시뮬레이션 문제이고 문제에 있는 그대로 작성하여 풀었다.

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

어렵지 않은 문제였다

 


#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

int N, M;
int r, c, d;
int room[50][50] = { 0, };
int clean[50][50] = { 0, };
int dr[4] = { -1,0,1,0 };
int dc[4] = { 0,1,0,-1 };
int main() {
    int i, j, break_chk, ddir, tmp;
    scanf("%d %d", &N, &M);
    scanf("%d %d %d", &r, &c, &d);
    for (i = 0; i < N; i++) {
        for (j = 0; j < M; j++) {
            scanf("%d", &room[i][j]);
        }
    }

    int answer = 0;
    while (1) {
        if (!clean[r][c]) {
            clean[r][c] = 1;
            answer++;
        }
        break_chk = 0;
        for (ddir = 1; ddir < 5; ddir++)
        {
            tmp = (d - ddir + 4) % 4;
            if (0 <= r + dr[tmp] && r + dr[tmp] < N && 0 <= c + dc[tmp] && c + dc[tmp] < M) {
                if ((!clean[r + dr[tmp]][c + dc[tmp]]) && (!room[r + dr[tmp]][c + dc[tmp]])) {
                    r += dr[tmp];
                    c += dc[tmp];
                    d = tmp;
                    break_chk = 1;
                    break;
                }
            }
        }
        if (!break_chk) {
            if (0 <= r - dr[d] && r - dr[d] < N && 0 <= c - dc[d] && c - dc[d] < M) {
                if (room[r - dr[d]][c - dc[d]])
                    break;
                r -= dr[d];
                c -= dc[d];
            }
        }
    }

    printf("%d\n", answer);

    return 0;
}

C에서는 (-3 % 4) 이런 문법이 적용되지 않아서 4를 더 더해서 사용했다.

나머지는 파이썬과 같은 코드 이다.