백준 19237 어른 상어

wook2·2022년 5월 21일
0

알고리즘

목록 보기
93/117

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

특별한 알고리즘 없이 구현하는 문제이다.
여러가지 구현문제들을 이리저리 치여보면서 느낀점은, 초기단계에서 어떻게 구현할 것인가 머리속으로 그려놓아야 한다는 것이다.
이런 구현 문제들은 초기단계에 데이터들을 번거롭게 저장해 놓아서, 후에 참조하는데 자꾸 머리를 쓰게되면, 그것대로 시간이 계속 흐른다고 생각한다.
그렇기 때문에 무작정 덤비기 보다는 어떤 자료형을 쓸지, 어떤 단계로 나누어 함수를 어떤 단위로 나눌지를 생각해야 한다.

일단 5x5 보드이기 때문에 배열에 어느정도 데이터를 저장해 놓아도 괜찮았고, 그림에 나와있는 상어들의 상태를 어떻게 나타낼까를 고민했었다.
각각의 위치에는 상어 번호, 방향, 냄새시간을 저장해 놓았다.

이제 상어를 움직이는 함수를 만들어야 하는데,
먼저 빈 공간이 있는지 확인하고 있다면, 냄새가 있는 공간까지 체크하는 로직까지 넘어가면 안된다.
만약 빈 공간이 없다면 냄새가 있는 공간들 중, 방향을 골라야 한다.

위의 단계를 거쳐 가능한 방향들을 저장해 놓았다면, 방향의 우선순위를 하나씩 꺼내면서 해당 방향이 후보방향에 있다면, 그 방향을 바로 선택하면 된다.

또한, 상어끼리 먹히는 부분을 구현해야 하는데, 잘 생각해보면 번호가 낮은 상어 순서대로 옮기면, 번호가 큰 상어가 이동할때 해당 위치에 상어가 있다면 해당 상어는 번호가 작은 상어에게 먹힌 것으로 판단할 수 있다.

def difuse():
    for i in range(n):
        for j in range(n):
            if board[i][j][0] != 0:
                if board[i][j][2] == 1:
                    board[i][j] = [0,0,0]
                else:
                    board[i][j][2] = board[i][j][2] - 1
def move():
    shark_after = []
    for x in range(n):
        for y in range(n):
            if board[x][y][0] != 0 and board[x][y][2] == k:
                f_number = board[x][y][0]
                pos = []
                pri = priority[f_number][board[x][y][1]]
                for i in range(4):
                    nx = x + dx[i]
                    ny = y + dy[i]
                    if 0 <= nx < n and 0 <= ny < n and board[nx][ny][0] == 0:
                        pos.append(i)
                if len(pos) > 0:
                    for pr in pri:
                        if pr in pos:
                            d = pr
                            break
                    shark_after.append([x,y,d,f_number])
                    continue
                pos = []
                for i in range(4):
                    nx = x + dx[i]
                    ny = y + dy[i]
                    if 0 <= nx < n and 0 <= ny < n and board[nx][ny][0] == f_number:
                        pos.append(i)
                if len(pos) > 0:
                    for pr in pri:
                        if pr in pos:
                            d = pr
                            break
                    shark_after.append([x,y,d,f_number])
    difuse()
    shark_after.sort(key = lambda x:x[3])
    for shark in shark_after:
        x,y,d,f_num = shark
        nx = x + dx[d]
        ny = y + dy[d]
        if board[nx][ny][0] != 0 and f_num > board[nx][ny][0]:
            continue
        board[nx][ny][0] = f_num
        board[nx][ny][1] = d
        board[nx][ny][2] = k

def check():
    c = 0
    for i in range(n):
        for j in range(n):
            if board[i][j][0] != 0 and board[i][j][2] == k:
                c += 1
    if c == 1:
        return True
    else:
        return False

n,m,k = list(map(int,input().split()))
board = [[] for i in range(n)]
dx = [-1,1,0,0]
dy = [0,0,-1,1]
for i in range(n):
    lst = list(map(int,input().split()))
    for j in range(n):
        board[i].append([lst[j],0,0])
direction = list(map(int,input().split()))
cnt = 0
for i in range(n):
    for j in range(n):
        if board[i][j][0] != 0:
            cnt += 1
            board[i][j][1] = direction[board[i][j][0]-1]-1
            board[i][j][2] = k
priority = [[]]
for i in range(cnt):
    x = []
    for j in range(4):
        lst = list(map(int,input().split()))
        lst = list(map(lambda x:x-1,lst))
        x.append(lst)
    priority.append(x)

for i in range(1000):
    move()
    if check():
        print(i+1)
        exit(0)
    # for row in board:
    #     print(row)
    # print()
print(-1)


profile
꾸준히 공부하자

0개의 댓글