일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 삼성SW역량테스트
- vocabulary
- 공수1
- homogeneous
- 공수 문제풀이
- SW역량테스트
- 문제풀이
- Problem Set 1.4
- 미분방정식
- English
- Homogeneous ODEs
- 비제차 상미분 방정식
- Nonhomogeneous ODEs
- Python
- 대학
- 코딩테스트
- 백준
- 맛집
- Ode
- Problem set 2.7
- Advanced Engineering Mathematics
- 공업수학
- 공수
- 미방
- 영어회화
- Problem set 1.5
- Conversation
- ODEs
- kreyszig
- 공학수학
- Today
- Total
한걸음
[221004] 백준 19327 : 어른 상어 본문
https://www.acmicpc.net/problem/19237
1. 딕셔너리의 적극적인 활용
상어의 위치를 계속해서 추적해줘야 하는데, 좌표 정보를 어떻게 업데이트할 것인가 고민을 많이 했다.
기존에 자주 하던 방식은 리스트에 [번호, x, y]값을 지정해서 추가시켜주는 것이었는데, 이번에는 뭔가 번호 한 번 검색하면 바로바로 뜨게 함으로써 인덱싱 및 좌표 값 수정하는 데 있어서 구구절절 코딩하고 싶지 않았다. 그래서 딕셔너리를 사용했다. 각 상어에 따른 이동 규칙도 딕셔너리로 만들어 주었다. 예제 1번에서의 1번 상어의 딕셔너리 정보는 다음과 같이 정리할 수 있다.
아쉬운 부분은, 이동규칙에 따른 리스트를 추출할 때에는 빈 배열이 들어가 있지 않아서 1을 빼줘야만 했다. 위의 그림에서는 바라보는 방향 인덱스 번호가 0~3으로 지정되어있기 때문이다. 할 수는 있는데, 이 정도는 머릿속으로 해결 가능하겠다 싶어서 안 함. 물론 좋은 코딩 습관은 아니다. 남들이 보면 대환 장할 수준의 레거시 코드가 될 수 있기 때문이다. 역량테스트를 위한 시험문제풀이이니 적당히 넘어가도록 하자. 하지만 현실 코딩에서는 그러면 안 됨.
2. 상어 냄새 묻히기와 시간 추가, 그리고 이동하기
이 문제의 주의할 점은 바로 상어의 위치를 추적하는 것이다. 코드 내용상 순서가 살짝 뒤바뀌는 것만으로도 오답 판정을 받는다. 그만큼 반복문 안에서 조건들을 잘 이행해주는 것이 중요하다. 해당 문제에서는
"상어가 냄새를 묻히고"
"1초 뒤"
"상어가 이동한다"
라고 되어있다.
이대로 정확하게 진행해줘야 한다. 상어가 이동하면서 냄새 묻히고 없애고 한 번에 구현하려고 했다가는 반례 폭격 바로 맞아버린다. 따라서 난 여기에 대한 흐름도를 다음과 같이 구상했다.
3. 전체 코드
메모리 : 116252 KB, 시간 : 228 ms, 풀이 시간 : 75 min
N, M, k = map(int, input().split())
board = [[[0, 0] for _ in range(N)] for _ in range(N)] # 상어 번호, 상어 냄새
s_coord = {}
for i in range(N):
tmp = list(map(int, input().split()))
for j in range(N):
if tmp[j] != 0 :
s_coord[tmp[j]] = [i, j]
d_info = list(map(int, input().split()))
d_spec = {}
for i in range(M):
temp = []
for _ in range(4):
temp.append(list(map(int, input().split())))
d_spec[i+1] = temp
dx = [0, -1, 1, 0, 0]
dy = [0, 0, 0, -1, 1]
def solve():
time = 0
while True :
check_cnt = 0
for i in range(M):
if s_coord[i + 1] : # 있는 경우에만 배치
x, y = s_coord[i + 1]
if board[x][y][0] != i + 1 and board[x][y][1] == k : # 중복 위치
num1, num2 = board[x][y][0], i + 1
board[x][y][0] = min(board[x][y][0], i + 1)
if num1 < num2 : s_coord[num2] = []
else : s_coord[num1] = []
check_cnt += 1
else : board[x][y][0] = i + 1
board[x][y][1] = k
else :
check_cnt += 1
if M - check_cnt == 1 : break
if time > 1000 : break
time += 1
for i in range(M): # Move
if s_coord[i + 1] :
x, y = s_coord[i + 1]
d_temp = d_spec[i+1][d_info[i]-1] # 이동 규칙 배열
# 최초 이동 실시
# 인접한 곳 중 빈 곳 먼저 가자
cnt = 0
for d in range(4) :
nx = x + dx[d_temp[d]]
ny = y + dy[d_temp[d]]
if 0 <= nx < N and 0 <= ny < N and board[nx][ny][1] == 0 :
s_coord[i + 1] = [nx, ny]
# 방향도 바꿔줘야함
d_info[i] = d_temp[d]
break
else : cnt += 1
if cnt < 4 :
continue
else :
for d in range(4):
nx = x + dx[d_temp[d]]
ny = y + dy[d_temp[d]]
if 0 <= nx < N and 0 <= ny < N and board[nx][ny][0] == i + 1 :
s_coord[i + 1] = [nx, ny]
d_info[i] = d_temp[d]
break
for i in range(N):
for j in range(N):
if board[i][j][1] > 0 :
board[i][j][1] = max(board[i][j][1] - 1, 0)
if board[i][j][1] == 0 :
board[i][j][0] = 0
return time
result = solve()
if result > 1000 :
print(-1)
else :
print(result)
'Coding Test' 카테고리의 다른 글
[221006] SWEA 5650 : 핀볼게임 (1) | 2022.10.06 |
---|---|
[221005] 백준 17837 : 새로운 게임 2 (1) | 2022.10.05 |
[221003] 백준 2573 : 빙산 (0) | 2022.10.03 |
[221003] 백준 17822 : 원판 돌리기 (0) | 2022.10.03 |
[221001] 백준 21608 : 상어 초등학교 (0) | 2022.10.01 |