[백준 삼성기출 X] 어른 상어(python)

이진규·2022년 10월 6일
1

백준(PYTHON)

목록 보기
99/115

문제

https://www.acmicpc.net/problem/19237

나의 코드

"""

"""

import copy

n, m, k = map(int, input().split()) # n : 격자크기, m : 상어의 마리수, k : 냄새가 사라지는 시간
pan = [ list(map(int, input().split())) for _ in range(n) ] # 상어의 위치(번호)
smell = [ [ [0, 0] for _ in range(n)] for _ in range(n) ] # 상어의 냄새와 번호
s_dir = [0] + list(map(int, input().split())) # 상어의 방향 / # 1, 2, 3, 4 = 위, 아래, 왼쪽, 오른쪽
s_pri = [ [] for _ in range(m+1) ] # 상어의 이동 우선순위 / # 위, 아래, 왼, 우 일때 우선순위

for i in range(1, m+1):
    for _ in range(4):
        tmp = list(map(int, input().split()))
        s_pri[i].append(tmp)

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

def s_smell(k): # 상어의 냄새와 번호 업데이트
    for i in range(n):
        for j in range(n):
            if pan[i][j] != 0:
                smell[i][j][0], smell[i][j][1] = k, pan[i][j]

def smell_down():
    for i in range(n):
        for j in range(n):
            if smell[i][j][1] == 0: # 상어가 없다면 stop
                continue
            if smell[i][j][0] == 1: # 타이머가 1이라면 0으로 리셋
                smell[i][j][0], smell[i][j][1] = 0, 0
            else:
                smell[i][j][0] -= 1

def move(pan):
    global out

    s = copy.deepcopy(pan)
    for i in range(n):
        for j in range(n):
            if pan[i][j] == 0:
                continue
            s_n = pan[i][j]
            d = s_dir[s_n]
            x, y = i, j
            what = False # 상어가 빈칸을 향해 이동했는지 확인하는 변수

            for p in range(4):
                md = s_pri[s_n][d-1][p] # 상어의 번호에서 방향 그리고 4방향이니 p로 설정
                mx = x + dx[md-1]
                my = y + dy[md-1]

                if not (0 <= mx < n and 0 <= my < n):
                    continue

                if smell[mx][my][1] == 0: # 이동하려는 곳이 상어 냄새가 없을 때
                    if s[mx][my] == 0: # 실제 상어도 없는 빈칸이라면
                        s[mx][my] = pan[x][y] # 이동하려는 칸에 상어 번호 업데이트
                        s[x][y] = 0
                    else: # 실제 다른 상어가 있다면
                        if s[mx][my] > s[x][y]: # 이동하려는 곳의 상어가 더 작으면 이동
                            s[mx][my] = pan[x][y]
                        out += 1 # 없어진 상어의 마리 수
                        s[x][y] = 0
                    s_dir[s_n] = md # 상어 이동 후 바라보고 있는 방향 갱신
                    what = True
                    break

            if what: # 만약 현재 상어가 이동했으면 다음 상어가 움직일 수 있게 그만두고, 현재 상어가 이동을 못했으면 자기 냄새가 있는 곳을 찾아가기 위해 계속 실행
                continue

            for p in range(4):
                md = s_pri[s_n][d - 1][p]
                mx = x + dx[md - 1]
                my = y + dy[md - 1]

                if not (0 <= mx < n and 0 <= my < n):
                    continue
                if smell[mx][my][1] == s_n: # 냄새가 있는곳이 자기 냄새가 맞으면
                    s[mx][my] = pan[x][y]
                    s[x][y] = 0
                    s_dir[s_n] = md
                    break

    return s

time = 0 # 시간
out = 0 # 상어가 잡아 먹히는 걸 세기 위한 변수

while True:
    if time >= 1000:
        time = -1
        break

    s_smell(k) # 상어 냄새 업데이트
    pan = move(pan) # 상어 이동 후 격자판은 복사해서 저장
    time += 1
    if out == m-1: # 만약 1번 상어를 제외하고 다 잡아먹혔으면 stop
        break
    smell_down()

print(time)

    

설명

빡구현 문제

참고 자료

https://developer-ellen.tistory.com/69

profile
항상 궁금해하고 공부하고 기록하자.

0개의 댓글