본문 바로가기

카테고리 없음

Baekjoon 17143. 낚시왕 / Python

728x90

17143. 낚시왕

난이도 : 골드 1
소요 시간 : 50분
날짜 : 2024.12.26
언어 : 파이썬
알고리즘 유형 : 구현, 시뮬레이션

설명 보기전에 문제 풀어보러 가기

1. 문제 설명

  1. 낚시왕이 오른쪽으로 한 칸 이동한다.
  2. 낚시왕이 있는 열에 있는 상어 중 제일 가까운 상어를 잡는다.
    • 잡힌 상어는 사라진다.
  3. 상어가 이동한다.
    • 상어진 주어진 속도로 이동하고, 경계와 만나면 방향을 반대방향으로 바꾸어 이동한다.
    • 방향이 바뀌어도 속력은 유지한다.
    • 상어가 이동을 마친 후에, 한 칸에 상어가 두 마리 이상 있다면, 크기가 큰 상어가 작은 상어를 모두 잡아먹는다.
  4. 낚시왕이 잡은 상어의 크기의 합을 구한다.

2. 해결 방식

입력

  1. 격자판의 크기 R, C, 상어의 수 M
  2. M개의 줄에 입력
    • 상어의 위치 r,c, 속력 s, 이동방향 d, 크기 z

해결

  1. 상어의 기록을 2차원 배열(fields)과 딕셔너리(sharks)를 이용한다.
    • 2차원 배열의 값은 상어의 번호, 상어가 없다면 -1이다.
    • 딕셔너리는 키, 값에 상어의 번호, 상어의 정보를 저장한다.
  2. 낚시왕 이동
    • 낚시왕 좌표의 열값에 1 더해주면 끝
  3. 상어 잡기
    • 낚시왕 열값에서 행을 0부터 증가시키면서 상어를 찾는다.
    • fields[낚시왕열값][행번호]의 값이 -1이 아닌 경우 상어가 있는 것
    • 상어를 찾으면 res에 상어크기를 더해주고, 상어를 없애준 후, 함수를 종료한다.
  4. 상어 이동
    • new_fields와 new_sharks를 통해 새로운 상어의 위치를 기록할 2차원 배열과 딕셔너리를 새로 만들어준다.
    • 상어가 있는 sharks 딕셔너리를 전부 순회하며 이동시킨다.
    • 상어 이동시 경계를 만나면 방향을 바꿔줄 것!!!
    • 이동한 곳에 상어가 이미 존재한다면
      • 이미 있는 상어가 더 크다면, 할 게 없음.
      • 새로 온 상어가 더 크가면, new_fields[r][c]값을 최신화하고, new_sharks딕셔너리에 새로운 상어를 등록하고, 기존 상어를 제거한다.
    • new_fields와 new_sharks를 기존 fields, sharks에 할당한다.

3. 정답 코드

import sys
sys.stdin = open("C:/Users/ghtjd/Desktop/tmp/python/input.txt", "r")

# input = sys.stdin.readline

from collections import defaultdict

R, C, M = map(int, input().split())
fields = [[-1] * C for _ in range(R)]
sharks = defaultdict(int)
for shark_idx in range(M):
    r, c, s, d, z = map(int, input().split())
    fields[r - 1][c - 1] = shark_idx
    sharks[shark_idx] = (r - 1, c - 1, s, d, z)

# 낚시왕 우로 1보
man_r, man_c = 0, -1
def move_right():
    global man_c
    man_c += 1
    return

# 상어 잡기
res = 0
def fishing():
    global res
    for i in range(R):
        shark_idx = fields[i][man_c]
        if shark_idx == -1:continue
        else:
            res += sharks[shark_idx][4]
            del sharks[shark_idx]
            fields[i][man_c] = -1
            return

# 상어 이동 : 1상, 2하, 3우, 4좌
direction = [0, -1, 1, 1, -1]
def move_shark():
    new_fields = [[-1] * C for _ in range(R)]
    new_sharks = defaultdict(int)

    for shark_idx, shark in sharks.items():
        if not shark:continue
        r, c, s, d, z = shark
        # 상하 이동
        if d in [1, 2]:
            s %= 2 * (R - 1)
            nr = r + s * direction[d]
            if nr < 0:
                nr = -nr
                d = 2
            if nr >= R:
                nr = 2 * (R - 1) - nr
                d = 1
            if nr < 0:
                nr = -nr
                d = 2
            r = nr
        # 좌우 이동
        if d in [3, 4]:
            s %= 2 * (C - 1)
            nc = c + s * direction[d]
            if nc < 0:
                nc = -nc
                d = 3
            if nc >= C:
                nc = 2 * (C - 1) - nc
                d = 4
            if nc < 0:
                nc = -nc
                d = 3
            c = nc

        # 가려는데 다른 상어 없다
        if new_fields[r][c] == -1:
            new_fields[r][c] = shark_idx
            new_sharks[shark_idx] = (r, c, s, d, z)
        # 가려는데 다른 상어 있다
        else:
            other_idx = new_fields[r][c]
            if sharks[other_idx][4] < z:    # 지금 상어가 이기면
                new_fields[r][c] = shark_idx
                new_sharks[shark_idx] = (r, c, s, d, z)
                del new_sharks[other_idx]

    return new_sharks, new_fields

for _ in range(C):
    move_right()
    fishing()
    sharks, fields = move_shark()
    print(fields)

print(res)
반응형