https://www.acmicpc.net/problem/1347
1347번: 미로 만들기
홍준이는 미로 안의 한 칸에 남쪽을 보며 서있다. 미로는 직사각형 격자모양이고, 각 칸은 이동할 수 있거나, 벽을 포함하고 있다. 모든 행과 열에는 적어도 하나의 이동할 수 있는 칸이 있다. 홍
www.acmicpc.net
# import sys
# N=int(sys.stdin.readline())
# Table = list(sys.stdin.readline())
"""
초기 위치와 바라보는 방향 설정 및 이동했던 좌표를 저장할 리스트를 생성
명령어를 하나씩 수행하며 위치 좌표와 방향을 변경하며 이동했던 좌표를 저장
이동하면서 찍힌 좌표의 최대값과 최소값의 차이로 최대 변의 길이를 계산
계산된 크기로 이차원배열을 생성 후 이동했던 좌표의 정보를 바탕으로 미로 완성
완성된 미로를 출력
"""
"""다른분의 코드 분석"""
'''
dx, dy = [-1, 0, 1, 0], [0, 1, 0, -1] # 방향 전환을 위해서 사용 dx=상하 dy=좌우
command_length = int(input()) # 명령 항목들의 길이 입력 받음
commands = input() # 문자열 형태로 입력 받음
dir = 2 # 이건 뭐지(아마 방향 설정하는데 쓰이는듯 <북쪽: 0, 동쪽: 1, 남쪽:2 ,서쪽:3> )
pos = [0, 0] # 현재 좌표를 0,0으로 설정
x_list = [0] # 이건뭐지 (X축에서 이동한 과정이 담기는 리스트)
y_list = [0] # 이건 뭐지 (Y축에서 이동한 과정이 담기는 리스트)
for command in commands: # 입력받은 명령 문자열을 바탕으로 반복문 실행 (문자열을 앞에서부터 하나씩 꺼내 받는 형식)
if command == 'L': # 만약 해당 문자가 Left이면?
dir = (dir - 1) % 4 # 연산을 통해 현재 dir는 1이 된다.(동쪽을 보는 형태)
elif command == 'R': # 연산을 통해 현재 dir는 3이 된다.(서쪽을 보는 형태)
dir = (dir + 1) % 4 # %4 연산을 하는 이유는 LLLL식으로 문자열이 들어오면 한바퀴 돌아서 그래도인것과 같은 형태이기 떄문
elif command == 'F': # 만약 해당 문자열이 Foward 이면 실행
x, y = pos # x와 y에 각각 0,0이 들어간다 (이런식으로도 쓸수가 있구나)
nx, ny = x + dx[dir], y + dy[dir] #현재 위치 + (바라보고있는 방향으로 Foward(전진))해서 현재 좌표 설정
x_list.append(nx) #이동한 좌표를 X리스트에 더해줌
y_list.append(ny) #이동한 좌표를 Y리스트에 더해줌
pos = [nx, ny] # 현재 위치를 수정 한다.
max_x, min_x, max_y, min_y = max(x_list), min(x_list), max(y_list), min(y_list) # 얼마만큼 X,Y의 이동반경인지 max와 min을 사용해 이들이 어디까지 돌아다녔나 확인
N, M = max_x - min_x + 1, max_y - min_y + 1 #최대값-최소값+1 을 통해 움직인 범위 측정 완료
start_x, start_y = abs(min_x), abs(min_y) # 최소값은 음수가 나올수 있으므로 절대값abs를 활용 처음 영향을 미친 곳
# 이 부분을 이동시작점으로 잡고 #을 .으로 바꿔줄 예정
maze = [['#'] * M for _ in range(N)] # ['#']으로 2차원 배열을 초기화 하는 과정
for x, y in zip(x_list, y_list): #zip(리스트1, 리스트2)은 2개이상의 리스트에서 같은 위치(인덱스가 같다)에 있는 요소들을 쌍으로 묶어서 튜플 형태로 처리하는 과정
maze[start_x + x][start_y + y] = '.' #실제 이동 지점을 '#'에서 '.'으로 바꿔주는 과정
for line in maze: # '.'수정이 끝난 2차원 리스트를 바탕으로 '구분자'.join(리스트) 형태를 통해 문자열 형태로 연결한다
print("".join(line))
'''
"""
''.join(리스트) --> 공백없이 리스트를 문자열로 변환할때 쓰는 과정
a=''
a+=str(['1']) 이런식으로 과정이 한번에 담겨있는듯
'구분자'.join(리스트)
"""
# 위치 이동 공식 설정(첫 지점을 0,0으로 잡고 , 동서남북 방향을 어떻게 표현할건지 설정)
import sys
N=int(sys.stdin.readline())
Move=sys.stdin.readline().strip()
#상하 좌우 (1,0) (0,-1) (-1,0) (0,1) 이렇게 4가지 방향으로 움직이는 쌍이 있다고 생각하면 편하다!
dx=[-1,0,1,0]
dy=[0,1,0,-1]
watch_position=2 # 북동남서 0 1 2 3, 난 현재 남쪽을 보고 있는 상황
now_stand=[0,0]
Moving_X=[0] # X가 움직인 좌표 흔적을 저장 (처음 위치는 0인것도 넣어주자)
Moving_Y=[0] # Y가 움직인 좌표 흔적을 저장 (처음 위치는 0인것도 넣어주자)
for M in Move: # 문자열을 앞에서 부터 하나씩 떼어가면서 생각을 한다.
if M=='L': #왼쪽을 보고 있는 상황
watch_position=(watch_position-1)%4 # 0-1이면 음수가 되는 상황이 발생하므로 나머지연산자와 4를 사용
elif M=='R': # 오른쪽을 보고 있는 상황
watch_position=(watch_position+1)%4
elif M=='F': # 전진을 하는 상황, 좌표 수정이 필요한 상황
nx,ny = now_stand[0]+dx[watch_position], now_stand[1]+dy[watch_position] #현재위치를 바탕으로 좌표이동을 실시 한다
Moving_X.append(nx) #X축 리스트에 더해주기
Moving_Y.append(ny) #Y축 리스트에 더해주기
now_stand=[nx, ny] #다시 현재 위치를 수정 한다.
#오케이 이제 이동 끝났어 그럼 좌표 설정 해줘야지
Rows_cnt = max(Moving_X)-min(Moving_X)+1
Colums_cnt = max(Moving_Y)-min(Moving_Y) +1
ans_list = [['#']*Colums_cnt for _ in range(Rows_cnt)] #2차원 배열 초기화
#시작 지점 잡기
start_x = abs(min(Moving_X ))
start_y = abs(min(Moving_Y))
for x,y in zip(Moving_X, Moving_Y):
ans_list[start_x+x][start_y+y]='.'
for k in ans_list:
print(''.join(k))
<알고 넘어가야 하는점>
정말 어려운 문제라고 생각한다. 문제을 풀면서 좌표 이동을 하는 경우는 이렇게 풀어야 한다는걸 깨달은것 같다.
dx, dy를 통해서 (1,0) (-1,0) (0,1) (0,-1) 방향으로 좌표 이동을 실시하는점과, 북동남서 방향을 0~3 까지의 숫자로 각각 매칭하여서 인덱스 번호로 사용, 방향을 이동하는게 신기하였다.
현재 위치를 (0,0)으로 잡고 방향은 남쪽을 보고있으니 숫자 2를 선택 (나중에 dx,dy에서의 인덱스 번호로 사용될 예정이다.)
이후 2차원 # 초기화된 배열을 만들고 zip(리스트1, 리스트2)를 활용해서 두 리스트의 같은 인덱스 번호에 위치한 값을 순차적으로 x,y에 넣어서 # 을 . 으로 바꾼뒤 구분자.join(배열의 요소 하나) 를 사용해서 출력을 진행 한다.(join은 2차원배열 형식에 맞게 행과 열을 인간이 생각하는 그대로 출력 해준다. (3*3의 2차원 배열이면 형식에 맞게 출력을 3*3형식으로 자동 줄바꿈을 넣어준다고 생각하면 편하다, 한줄에 리스트 하나씩만을 처리 한다.))
'백준 알고리즘 문제풀이' 카테고리의 다른 글
[Python] 2164번: 카드2 (0) | 2023.01.01 |
---|---|
[Python] 2609번: 최대공약수와 최소공배수 (0) | 2023.01.01 |
[Python] 9012번: 괄호 (0) | 2023.01.01 |
파이썬 하면서 배워야 하는 것들 (0) | 2022.12.31 |
[Python] 2108번: 통계학 (0) | 2022.12.30 |