알고리즘

[알고리즘|파이썬] 백준 13901 로봇

따오잉 2025. 2. 22. 19:22

문제 링크: https://www.acmicpc.net/problem/13901

 

📌 문제 탐색하기

시간 제한: 1초
메모리 제한: 256 MB

 

📌 풀이하기 

로봇의 조건

  • 로봇은 사용자가 지정한 방향을 일직선으로 움직인다.
  • 이동 중 이나 방문한 지역, 장애물을 만날 경우 로봇은 사용자가 지정한 다음 방향으로 움직인다.
  • 사용자가 지정한 다음 방향이 없다면 맨 처음 방향으로 돌아가서 위의 과정을 반복한다.
  • 로봇이 움직일 수 없을 경우 동작을 멈춘다.

예제 1.

방 크기가 3* 3이고

장애물이 (1, 0)에 있으며

시작 위치는 (1,1)

해빈이가 지정한 방향이 (상, 하, 좌, 우) 일 때,

로봇의 마지막 위치는 (0, 0)이다.

 

1. 시작: (1, 1)

2. [상] 이동: (0, 1)

3. 벽을 만났으므로 [하]로 이동 -> (1, 1)는 이미 방문했으므로 다음 방향으로 넘어감 -> [좌]로 이동 : (0, 0)

4. 벽을 만났으므로 [우]로 이동 -> (0, 1)은 이미 방문 했으므로 다음 방향으로 넘어감 -> [상] 은 벽이므로 이동 불가. 다음 방향으로 넘어감 -> [하] 는 장애물이 있으므로 이동 불가. 다음 방향으로 넘어 감 -> [좌] 는 벽이므로 이동 불가. 다음 방향으로 넘어감 -> 더이상 움직일 수 없으므로 종료.

그러므로 로봇의 이동은 (1, 1) -> (0, 1) -> (0, 0)이 되고, 마지막 위치는 (0, 0)이 된다.

 

🤖 로봇을 어떻게 움직이게 할 것인가?

  • 로봇은 사용자가 지정한 방향을 일직선으로 움직인다.
  • 이동 중 이나 방문한 지역, 장애물을 만날 경우 로봇은 사용자가 지정한 다음 방향으로 움직인다.
  • 사용자가 지정한 다음 방향이 없다면 맨 처음 방향으로 돌아가서 위의 과정을 반복한다.
  • 로봇이 움직일 수 없을 경우 동작을 멈춘다.

로봇의 조건을 그대로 코드로 옮겨야한다.

상하좌우를 [(-1, 0), (1, 0), (0, -1), (0, 1)] 로 변환할 수 있다.

또한 이미 방문한 지역은 갈 수 없으므로 방문한 위치를 따로 기록을 해주어야한다.


📌 코드 설계하기

1. 방 크기 입력 및 초기화

2. 장애물 개수 k 입력 후, k번 반복하여 장애물 위치를 입력받아 room1로 표시

3. 로봇 시작 위치 설정: room[sr][sc] = 1로 방문 표시

4. 이동 방향 입력 및 설정

  - 이동 방향 순서를 리스트(seq)로 입력받음

  - direction = [(-1, 0), (1, 0), (0, -1), (0, 1)] // 상하좌우

5. 로봇 이동 시뮬레이션

  - while 문을 사용하여 로봇이 이동할 수 없을 때까지 반복

  - 이동 가능하면 가야하는 방향으로 이동, 이동한 위치는 1로 채우기

  - 이동 불가하면 다음 방향으로 넘어가기

6. 최종 위치 출력 : sr, sc 값을 출력하여 로봇이 멈춘 위치를 표시


📌 시도 회차 수정 사항

1회차: 런타임 에러 (IndexError)

# 변경 전
if room[sr+i][sc+j] == 1 or sr+i < 0 or sr+i >= r or sc+j < 0 or sc+j >= c :

# 변경 후
if sr+i < 0 or sr+i >= r or sc+j < 0 or sc+j >= c or room[sr+i][sc+j] == 1 :

sr+i, sc+j가 각각 r, c를 넘는 경우 room[sr+i][sc+j] 조건을 if 문에서 먼저 확인하게 되면 index 에러가 날 수 있다.

그러므로 먼저 배열 조건에 넘지 않는지를 확인한 후에 배열 조회를 하도록 순서를 바꿔주면 된다.

 


📌 정답 코드

r, c = map(int, input().split())
room = [[0 for _ in range(c)] for _ in range(r)]
k = int(input())
for _ in range(k):
    br, bc = map(int, input().split())
    room[br][bc] += 1
sr, sc = map(int, input().split())
room[sr][sc] = 1 # 첫 위치 방문 표시
seq = list(map(int, input().split()))
direction = [(0, 0), (-1, 0), (1, 0), (0, -1), (0, 1)] # [0]은 안쓰는 값, 상하좌우
flag = True
idx = 0
count = 0

while flag:
    seq_now = seq[idx]
    now = direction[seq_now]
    i, j = now[0], now[1]
    if sr+i < 0 or sr+i >= r or sc+j < 0 or sc+j >= c or room[sr+i][sc+j] == 1 : # 다음을 못가는 경우
        idx += 1  # 다음 순서로 넘김
        idx %= len(seq)
        count += 1
        if count == 5:
            flag = False
    else: # 다음을 갈 수 있는 경우
        sr = sr+i
        sc = sc+j
        room[sr][sc] = 1
        count = 0
print(sr, sc)