카테고리 없음

[백준 23290번] 마법사 상어와 복제 (Python3)

rapun7el 2023. 2. 2. 15:06
import sys
input = sys.stdin.readline
dy = [-1,-1,0,1,1,1,0,-1]
dx = [0,-1,-1,-1,0,1,1,1]

def movefish():
  newocean = [[[] for i in range(4)] for i in range(4)]
  for y in range(4):
    for x in range(4):
      for d in ocean[y][x]:
        cant = True
        for i in range(8):
          y1,x1 = y+dy[(d+i)%8],x+dx[(d+i)%8]
          if 4>y1>=0 and 4>x1>=0 and [y1,x1] != shark and not smell[y1][x1]:
            newocean[y1][x1].append((d+i)%8)
            cant = False
            break
        if cant:
          newocean[y][x].append(d)
  return newocean

def moveshark(ocean):
  global shark
  y,x = shark
  maxcnt = -1
  for i in range(4):
    y1,x1 = y+dy[i*2],x+dx[i*2]
    if not (4>y1>=0 and 4>x1>=0):
      continue
    cnt1 = len(ocean[y1][x1])
    for j in range(4):
      y2,x2 = y1+dy[j*2],x1+dx[j*2]
      if not (4>y2>=0 and 4>x2>=0):
        continue
      cnt2 = len(ocean[y2][x2])
      for k in range(4):
        y3,x3 = y2+dy[k*2],x2+dx[k*2]
        if not (4>y3>=0 and 4>x3>=0):
          continue
        cnt3 = len(ocean[y3][x3])
        if k == (j+2)%4:
          cnt3 = 0
        if cnt1+cnt2+cnt3 > maxcnt:
          my1,my2,my3,mx1,mx2,mx3 = y1,y2,y3,x1,x2,x3
          maxcnt = cnt1+cnt2+cnt3
  shark = [my3,mx3]
  if ocean[my1][mx1]:
    smell[my1][mx1] = 3
  if ocean[my2][mx2]:
    smell[my2][mx2] = 3
  if ocean[my3][mx3]:
    smell[my3][mx3] = 3
  ocean[my1][mx1] = []
  ocean[my2][mx2] = []
  ocean[my3][mx3] = []
  return maxcnt

def smelldown():
  for i in range(4):
    for j in range(4):
      if smell[i][j]:
        smell[i][j] -= 1

def copyocean():
  for y in range(4):
    for x in range(4):
      for d in newocean[y][x]:
        ocean[y][x].append(d)

ocean = [[[] for i in range(4)] for i in range(4)]

M,S = map(int,input().split())
for i in range(M):
  a,b,c = map(lambda x:x-1,map(int,input().split()))
  ocean[a][b].append((2-c)%8)
smell = [[0]*4 for i in range(4)]
shark = [*map(lambda x:x-1,map(int,input().split()))]

cnt = M
for _ in range(S):
  cnt *= 2
  newocean = movefish()
  cnt -= moveshark(newocean)
  smelldown()
  copyocean()

print(cnt)

대놓고 실수하라고 만든것 같은 느낌이 드는 문제이다.

문제 자체는 어려운 점이 없는데 입력데이터가 너무 불친절해서 디버깅에 시간을 많이 소모했다.

 

가장 짜증났던 점은 물고기의 회전은 시계반대방향이고, 사전순서도 시계반대방향에 사전순서의 첫번째는 위 방향인데, 입력으로 주어지는 방향데이터는 좌 부터 시작하는 시계방향 순서라는 것이다.

왜 이런식으로 문제를 내는지...

 

이 외에도 실수하기 좋은 포인트를 몇 가지 소개하자면

1. 이미 갔던 방향으로 다시 돌아갈 수 있고, 이미 갔던 방향으로 다시 돌아갈 때, 두번째에 돌아갈 때는 상관없지만 세번째 움직임에서 돌아가는 경우 중복계산을 피해야 한다.

2. 문제에서는 x,y로 데이터를 주었는데 세로가 x고 가로가 y이다.

3. 사전순서에 주의해야한다.

 

등이 있다. 실수만 조심하면 구현 자체는 차근차근 읽어보면 쉽게 해결할 수 있다.

 

 

오늘의 교훈) 실수하지 말자