728x90
17143. 낚시왕
난이도 : 골드 1
소요 시간 : 50분
날짜 : 2024.12.26
언어 : 파이썬
알고리즘 유형 : 구현, 시뮬레이션
설명 보기전에 문제 풀어보러 가기
1. 문제 설명
- 낚시왕이 오른쪽으로 한 칸 이동한다.
- 낚시왕이 있는 열에 있는 상어 중 제일 가까운 상어를 잡는다.
- 잡힌 상어는 사라진다.
- 상어가 이동한다.
- 상어진 주어진 속도로 이동하고, 경계와 만나면 방향을 반대방향으로 바꾸어 이동한다.
- 방향이 바뀌어도 속력은 유지한다.
- 상어가 이동을 마친 후에, 한 칸에 상어가 두 마리 이상 있다면, 크기가 큰 상어가 작은 상어를 모두 잡아먹는다.
- 낚시왕이 잡은 상어의 크기의 합을 구한다.
2. 해결 방식
입력
- 격자판의 크기 R, C, 상어의 수 M
- M개의 줄에 입력
- 상어의 위치 r,c, 속력 s, 이동방향 d, 크기 z
해결
- 상어의 기록을 2차원 배열(fields)과 딕셔너리(sharks)를 이용한다.
- 2차원 배열의 값은 상어의 번호, 상어가 없다면 -1이다.
- 딕셔너리는 키, 값에 상어의 번호, 상어의 정보를 저장한다.
- 낚시왕 이동
- 낚시왕 좌표의 열값에 1 더해주면 끝
- 상어 잡기
- 낚시왕 열값에서 행을 0부터 증가시키면서 상어를 찾는다.
- fields[낚시왕열값][행번호]의 값이 -1이 아닌 경우 상어가 있는 것
- 상어를 찾으면 res에 상어크기를 더해주고, 상어를 없애준 후, 함수를 종료한다.
- 상어 이동
- 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)
반응형