19237번: 어른 상어

Jake_Young·2020년 10월 14일
0
post-thumbnail

👉문제 링크


느낀점

  • 역시나 힘들었다.
  • 시간은 딱 1시간 56분 걸렸다. 풀이는 역시나 지저분하다.

정답 코드 및 해설

# 위 아래 왼쪽 오른쪽 = 0, 1, 2, 3
d = [[0, -1], [0, 1], [-1, 0], [1, 0]]

world_size, shark_count, duration_time = map(int, input().split())
world_status = [list(map(int, input().split())) for _ in range(world_size)]  # 상어 위치(양수)나 빈 (0)인지
shark_status = {}  # 상어의 x, y, direction 정보를 갖고 있음
temp_input = list(map(lambda x: int(x) - 1, input().split()))
for shark in range(shark_count):
    shark_status[shark + 1] = temp_input[shark]
shark_priority = {}  # 상어 이동의 우선 순위가 키 벨류로... 키는 상어 번호, 벨류는 [[],[],[],[]] 4X4로
for shark in range(shark_count):
    shark_priority[shark + 1] = []
    for direction in range(4):
        temp_input = list(map(lambda x: int(x) - 1, input().split()))
        shark_priority[shark + 1].append(temp_input[:])

pheromon = [[[] for __ in range(world_size)] for _ in range(world_size)]
for y in range(world_size):
    for x in range(world_size):
        if world_status[y][x]:
            pheromon[y][x] = [world_status[y][x], 0]  # 누구 껀지, 몇 초 남았는지
            data = [x, y, shark_status[world_status[y][x]]]
            shark_status[world_status[y][x]] = data[:]
time = 0

# world_status, shark_status, shark_priority, pheromon

while time < 1000 and len(shark_status) != 1:
    time += 1
    # 상어 이동
    for shark in list(shark_status.keys())[:]:
        x, y, direction = shark_status[shark]
        vacant = []
        # 1. 상하좌우에 빈 칸이 있다면 우선순위에 따라 이동하기
        # - 기존 자리에 페로몬 남기기(pheromon이랑 world에 음수로 지속시간 남기기)
        for new_direction in range(4):
            dx, dy = d[new_direction]
            new_x, new_y = x + dx, y + dy
            if 0 <= new_x < world_size and 0 <= new_y < world_size:
                # 주의~!!!!!!!!!!!!!! 등호 넣을까 말까!!!!
                if not pheromon[new_y][new_x] or pheromon[new_y][new_x][1] < time - duration_time:
                    vacant.append(new_direction)
        priority = shark_priority[shark][direction]

        if vacant:
            #    - 빈 자리라면 새로운 상어 이동 시키기 + 방향 저장하기
            for next_direction in priority:
                if next_direction in vacant:
                    dx, dy = d[next_direction]
                    new_x, new_y = x + dx, y + dy
                    world_status[y][x] = 0
                    if world_status[new_y][new_x]:
                        # 그 자리에 이미 상어가 있다면, 지금 움직이려는 상어 삭제
                        del shark_status[shark]
                        del shark_priority[shark]
                    else:
                        # 새로운 상어 이동 시키기 + 방향 저장하기
                        world_status[new_y][new_x] = shark
                        shark_status[shark] = [new_x, new_y, next_direction]
                    break
        else:
            # 2. 빈 칸이 없다면 내 페로몬이 있는 자리 탐색하기
            vacant = []
            for new_direction in range(4):
                dx, dy = d[new_direction]
                new_x, new_y = x + dx, y + dy
                if 0 <= new_x < world_size and 0 <= new_y < world_size:
                    if not pheromon[new_y][new_x] or pheromon[new_y][new_x][0] == shark:
                        vacant.append(new_direction)
            #    - 우선 순위 높은 곳으로 이동하기 + 방향 저장하기
            for next_direction in priority:
                if next_direction in vacant:
                    dx, dy = d[next_direction]
                    new_x, new_y = x + dx, y + dy
                    if 0 <= new_x < world_size and 0 <= new_y < world_size:
                        world_status[y][x] = 0
                        world_status[new_y][new_x] = shark
                        shark_status[shark] = [new_x, new_y, next_direction]
                        break
    # 이동한 상어들 페로몬 남기기 시간으로 남기기
    for shark, value in shark_status.items():
        x, y, direction = value
        pheromon[y][x] = [shark, time]

if len(shark_status) == 1:
    print(time)
else:
    print(-1)
profile
자바스크립트와 파이썬 그리고 컴퓨터와 네트워크

0개의 댓글