천 리 길도 한 걸음부터

(다시 풀기) [python] BOJ 14499번: 날짜 계산 (220106) 본문

👩‍💻 STUDY/알고리즘

(다시 풀기) [python] BOJ 14499번: 날짜 계산 (220106)

눅눅한 김말이 2022. 1. 6. 16:45
 

14499번: 주사위 굴리기

첫째 줄에 지도의 세로 크기 N, 가로 크기 M (1 ≤ N, M ≤ 20), 주사위를 놓은 곳의 좌표 x, y(0 ≤ x ≤ N-1, 0 ≤ y ≤ M-1), 그리고 명령의 개수 K (1 ≤ K ≤ 1,000)가 주어진다. 둘째 줄부터 N개의 줄에 지

www.acmicpc.net

  결과   런타임 에러
  소요 시간   1시간 52분
  언어   Python 3

 

2일 동안 본 문제인데 주사위 오려서 굴려보고 이것저것 해봤으나 결국 풀지 못해 다른 분의 코드로 이해했다. 처음 문제를 봤을 때 풀 수 있을 것 같았는데 풀다 보니 [예제 입력 1]에 맞춰서 작성하고 문제에 맞게 수정하기로 마음먹었다. 지금 생각해보면 문제 해결에 좋지 못한 방식같다. 아래 코드에서 dice 변수를 2중 리스트로 했는데 이렇게 해서는 못 푼다.

# n, m, x, y, k = map(int, input().split())
# r, c = x, y

# data = []
# for i in range(n):
#   a, b = map(int, input().split())
#   data += [[a, b]]

# direction = list(map(int, input().split()))
# dice = [[0, 0, 0, 0], [0], [0]]

# dx = [1, -1, 0, 0]
# dy = [0, 0, -1, 1]

# for i in range(k):
#   x += dx[direction[i]-1]
#   y += dy[direction[i]-1]
#   r += dx[direction[i]-1]
#   c += dy[direction[i]-1]

#   if x > 2: x = 0
#   elif x < 0: x = 2
#   elif y > 3: y = 0
#   elif y < 0: y = 3
    
#   if 0 <= r <= m-1 and 0 <= c <= n-1:
#     if direction[i] == 1:
#       x += 2
#       if x == 3: x = 0
#       elif x == 4: x = 1
#       dice[x][y] = data[c][r]

#     elif direction[i] == 2:
#       x -= 2
#       if x == -2: x = 1
#       elif x == -1: x = 2
#       dice[x][y] = data[c][r]

#     elif direction[i] == 3:
#       y -= 2
#       if y == -2: y = 2
#       elif y == -1: y = 3
#       dice[x][y] = data[c][r]

#     elif direction[i] == 4:
#       y += 2
#       if y == 4: y = 0
#       elif y == 5: y = 1
#       dice[x][y] = data[c][r]
  결과   런타임 에러
  소요 시간   1시간 16분
  언어   Python 3

 

다음날 for문을 지우고 다시 건드려봤는데 생각을 잘못했다. 주사위가 어떻게 움직이느냐에 따라서 바닥면이 결정되는데 주사위 펼친 모양을 보고 한 행이 1, 4, 3 반복이고 한 열이 행 아래로 2, 6, 5 반복한다고 생각했다. 문제 정의를 이상하게 해서 코드가 이상하게 나왔다.

# n, m, x, y, k = map(int, input().split())

# data_x, data_y = [], []
# for i in range(n):
#   a, b = map(int, input().split())
#   data_x += [a]
#   data_y += [b]
# data = [data_x, data_y]

# direction = list(map(int, input().split()))
# # dice[0]은 사용하지 않음
# dice = [0, 0, 0, 0, 0, 0, 0]

# dx = [1, -1, 0, 0]
# dy = [0, 0, -1, 1]

# for i in range(k):
#   x += dx[direction[i]-1]
#   y += dy[direction[i]-1]

#   if 0 <= x <= m-1 and 0 <= y <= n-1:
#     if (y+1)%4 == 0:
#       dice[5] = data[x][y]

#     elif (y+1)%4 == 1:
#       if (x+1)%3 == 0:
#         dice[3] = data[x][y]

#       elif (x+1)%3 == 1:
#         dice[6] = data[x][y]

#       elif (x+1)%3 == 2:
#         dice[4] = data[x][y]

#     elif (y+1)%4 == 2:
#       dice[2] = data[x][y]

#     elif (y+1)%4 == 3:
#       dice[1] = data[x][y]

#   else:
#     x -= dx[direction[i]-1]
#     y -= dy[direction[i]-1]​
  결과   맞았습니다!!
  소요 시간   0분
  언어   Python 3

 

처음 풀이를 보고 '왜 이렇게 생각을 못 했을까?' 했는데 많은 문제를 다뤄보지 않았기 때문에 해결법이 안 떠올를 수밖에 없었다. import sys도 다시 생각이 났고 그동안 지도에서 x, y의 방향을 이동시킬 때 dx, dy 리스트의 값으로 했는데 함수로 정의해서 사용하는 방법 괜찮은 것 같다. dice = [0, 윗면, 앞면, 오른쪽, 뒷면, 왼쪽, 바닥면]이고 이전까지 if문 들어가기 전에 얼마만큼 움직일지 더해주고 else로 빼줬는데 if 조건문에서 처리해서 깔끔하다. 문제를 몇 번 읽었음에도 '주사위 바닥면'과 '지도의 한 칸' 둘 중 하나는 0이라는 조건을 몰랐다. 정신 차리고 풀어야겠다.

import sys
input = sys.stdin.readline

def dice_move(direction):
  if direction == 1:
    dice[1], dice[3], dice[4], dice[6] = dice[3], dice[6], dice[1], dice[4]
  elif direction == 2:
    dice[1], dice[3], dice[4], dice[6] = dice[4], dice[1], dice[6], dice[3]
  elif direction == 3:
    dice[1], dice[2], dice[5], dice[6] = dice[2], dice[6], dice[1], dice[5]
  elif direction == 4:
    dice[1], dice[2], dice[5], dice[6] = dice[5], dice[1], dice[6], dice[2]

def map_move(direction):
  if direction == 1: return 0, 1
  elif direction == 2: return 0, -1
  elif direction == 3: return -1, 0
  elif direction == 4: return 1, 0

n, m, x, y, k = map(int, input().split())
data = []

for i in range(n):
  data.append(list(map(int, input().split())))

command = list(map(int, input().split()))
dice = [0, 0, 0, 0, 0, 0, 0]

for i in command:
  a, b = map_move(i)
  
  if 0 <= x + a < n and 0 <= y + b < m:
    x += a
    y += b
    dice_move(i)

    if data[x][y] != 0:
      dice[1] = data[x][y]
      data[x][y] = 0

    else:
      data[x][y] = dice[1]

    print(dice[6])

알고리즘 문제 풀 때 시간을 느슨하게 잡지 말고 정한 시간 내에 못 풀면 정답보고 익히는 방식으로 가야겠다. 스스로가 생각하기에 특징이 오래 문제를 붙잡고 있는 것보다 모르면 약간의 시간을 주고 그래도 해결하지 못하면 답을 반복해서 학습할 때 더 효과적으로 공부할 수 있었다.