일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 다이나믹 프로그래밍
- DFS
- 문자열
- CSS
- 그래프 이론
- 웹 프론트엔드
- 자료구조
- 그래프 탐색
- BASIC
- 구현
- web
- 프로그래머스
- 백준
- 그래프이론
- 자바스크립트
- 브루트포스 알고리즘
- programmers
- JavaScript
- 딕셔너리
- 프로그래머스스쿨
- DP
- 너비 우선 탐색
- 정렬
- 알고리즘
- BFS
- 파이썬
- level2
- 스택
- lv2
- 그리디 알고리즘
Archives
- Today
- Total
DevLog:-)
[알고리즘][파이썬]14503-로봇청소 본문
반응형
문제
문제 이해
로봇청소기가 벽이 아닌 구간을 돌아다니며 청소를 하는 문제이다.
방의 크기/청소기 위치, 청소기 방향이 주어지고 벽은 1, 빈칸은 0으로 된 N*M 값을 받게 된다.
아래와 같이 로봇 움직임의 규칙이 나와있는데 이에 대한 이해와 숙지가 굉장히 중요한 거 같다.
- 현재 칸이 아직 청소되지 않은 경우, 현재 칸을 청소한다.
- 현재 칸의 주변 4 칸 중 청소되지 않은 빈 칸이 없는 경우,
- 바라보는 방향을 유지한 채로 한 칸 후진할 수 있다면 한 칸 후진하고 1번으로 돌아간다.
- 바라보는 방향의 뒤쪽 칸이 벽이라 후진할 수 없다면 작동을 멈춘다.
- 현재 칸의 주변 4 칸 중 청소되지 않은 빈 칸이 있는 경우,
- 반시계 방향으로 90∘ 회전한다.
- 바라보는 방향을 기준으로 앞쪽 칸이 청소되지 않은 빈칸인 경우 한 칸 전진한다.
- 1번으로 돌아간다.
+나의 실수 : 주변 4칸 중 청소되지 않은 빈칸이 있는 경우 반시계 방향으로 90도 회전한 후 바라보는 부분이 청소가
가능한지 판단해야하는데 바라보는 부분을 먼저 확인하고 청소가 불가능할 때부터 90도 회전하는 것인지 아는 바람에
코드 작성에 시간을 많이 소요했다. 😅
문제를 꼼꼼히 읽고 파악하는 것이 무엇보다 중요하다
코드 설계
조건에 따라 계속해서 청소와 주변탐색을 반복하는 특징이 있는 문제이다.
따라서 재귀함수를 사용했다.
clean이라는 함수를 통해 청소를 할 때마다 count변수로 횟수를 업로드했다.
청소 후 주변을 탐색하고 조건에 맞춰 다시 clean함수를 호출하거나 종료하도록 작성했다.
<현재 칸에서 주변 시계방향으로 탐색 후 결과에 따른 로봇의 동작>
- 0자리 발견 -> 해당자리를 인자로 clean함수 호출
- 0자리 없음 -> 후진 -> 후진가능 : clean함수 호출 / 후진 불가능: 함수 종료
+후진 가능 : 1이 아닐 때
+후진 불가능 : 1일 때
코드
import sys
n,m = map(int,sys.stdin.readline().strip().split())
x,y,z = map(int,sys.stdin.readline().strip().split())
g =[]
for _ in range(n):
g.append(list(map(int,sys.stdin.readline().strip().split())))
visited=[[False]*m for _ in range(n)]
#벽인지와 청소가 가능한지 판별하는 함수다.
def check(x,y):
if g[x][y] == 1:
return 1 #벽일때
if visited[x][y] :
return 2 #이미 청소했을 때
return 0
#청소할 자리를 받는다.
def clean(x,y,z,count): #자리+방향+count
if(check(x,y)==0): #청소한 자리 수 세기
count+=1
dx = [-1,0,1,0]
dy = [0,1,0,-1] #0,1,2,3 순서로 둠
visited[x][y] = True # 청소한 자리 기록하기
Z = z
#1)0발견 ->clean 함수 호출
for _ in range(4):
Z -=1 #시계방향을 돌리기
if(Z<0): Z =3
if(check(x+dx[Z],y+dy[Z])==0):
clean(x+dx[Z],y+dy[Z],Z,count)
return
#2)0발견 못함 -> 후진
if check(x-dx[z],y-dy[z])!=1: # 벽이 아니면 후진
clean(x-dx[z],y-dy[z],z,count)
return
else: #벽이면 중지
print(count)
return
clean(x,y,z,0)
추가 코드
import sys
N,M = map(int, sys.stdin.readline().strip().split())
x,y,z = map(int, sys.stdin.readline().strip().split())
g =[]
for i in range(N):
g.append(list(map(int,sys.stdin.readline().strip().split())))
count = 0
dx = [-1,0,1,0]#0,1,2,3
dy = [0,1,0,-1]
def clean(x,y,z):
global count
#청소
if(g[x][y]==0):
g[x][y] = 2
count +=1
#탐색
Z= z
#청소할 방이 있는가
for i in range(4):
Z = (Z+3) % 4
if(g[x+dx[Z]][y+dy[Z]]==0):
clean(x+dx[Z],y+dy[Z],Z)
return
#후진이 가능한가
if(g[x-dx[z]][y-dy[z]]!=1):
clean(x-dx[z],y-dy[z],z)
return
else:
return count
clean(x,y,z)
print(count)
반응형
'알고리즘 > 백준' 카테고리의 다른 글
[알고리즘][파이썬]1463-1로 만들기 (BFS/DP) (0) | 2023.07.05 |
---|---|
[알고리즘][파이썬]1371-가장 많은 글자 (0) | 2023.07.01 |
[알고리즘][파이썬]1969-DNA (1) | 2023.06.15 |
[알고리즘][파이썬]1120-문자열 (0) | 2023.06.14 |
[알고리즘][파이썬]1251-단어 나누기 (0) | 2023.06.14 |