1. 문제 접근 방법
- 내가 접근한 방법보다 나은 방법을 찾아서 학습했다
- 중요한 포인트가 몇 가지 있다
(1) for i in range(2*N-1)
-> 길이가 N일 때, 2*N-1번 회전이 됨을 이렇게 표시하였다
(2) d = i % 4
-> d를 0, 1, 2, 3이 번갈아 오도록 표시하였다
(3) d == 0 or d == 2
-> 왼쪽 방향, 오른쪽 방향일때만 time을 1 증가시켰다.
(4) left = [(1, 1, 0.01), (-1, 1, 0.01), (1, 0, 0.07), (-1, 0, 0.07), (1, -1, 0.1),
(-1, -1, 0.1), (2, 0, 0.02), (-2, 0, 0.02), (0, -2, 0.05), (0, -1, 0)]
-> x변화값, y변화값, 비율을 하나의 배열에 묶어서 표현했다
-> 특히, (0, -1, 0)을 맨 끝에 배치했다는 것이 중요하다
(5) right = [(x, -y, z) for x,y,z in left]
down = [(-y, x, z) for x,y,z in left]
up = [(y, x, z) for x,y,z in left]
- > 매우 매우 중요한 포인트. 이렇게 함으로써, 코드 구현량을 기하급수적으로 줄일 수 있다.
효율성을 위해서 반드시 필요한 코드
-> 다만, 방향 전환에 대한 이해가 있어야 하는 코드이다.
(6) def recount(s_x, s_y, direction):
global ans
if s_y < 0:
return
# 3. a, out_sand
total = 0 # a 구하기 위한 변수
for dx, dy, z in direction:
nx = s_x + dx
ny = s_y + dy
if z == 0: # a(나머지)
new_sand = sand[s_x][s_y] - total
else: # 비율
new_sand = int(sand[s_x][s_y] * z)
total += new_sand
if 0 <= nx < N and 0 <= ny < N: # 인덱스 범위이면 값 갱신
sand[nx][ny] += new_sand
else: # 범위 밖이면 ans 카운트
ans += new_sand
-> direction을 전달해줌으로써, 코드의 구현을 간단히할 수 있다
-> 여기서 나가는 것과 나가지 않는 것을 잘 판단해서 구분해줘야 한다.
2. 코드
# 모래 계산하는 함수
def recount(s_x, s_y, direction):
global ans
if s_y < 0:
return
# 3. a, out_sand
total = 0 # a 구하기 위한 변수
for dx, dy, z in direction:
nx = s_x + dx
ny = s_y + dy
if z == 0: # a(나머지)
new_sand = sand[s_x][s_y] - total
else: # 비율
new_sand = int(sand[s_x][s_y] * z)
total += new_sand
if 0 <= nx < N and 0 <= ny < N: # 인덱스 범위이면 값 갱신
sand[nx][ny] += new_sand
else: # 범위 밖이면 ans 카운트
ans += new_sand
N = int(input())
sand = [list(map(int, input().split())) for _ in range(N)]
# 2. 방향별 모래 비율 위치
left = [(1, 1, 0.01), (-1, 1, 0.01), (1, 0, 0.07), (-1, 0, 0.07), (1, -1, 0.1),
(-1, -1, 0.1), (2, 0, 0.02), (-2, 0, 0.02), (0, -2, 0.05), (0, -1, 0)]
right = [(x, -y, z) for x,y,z in left]
down = [(-y, x, z) for x,y,z in left]
up = [(y, x, z) for x,y,z in left]
s_x, s_y = N//2, N//2
ans = 0
dx = [0, 1, 0, -1]
dy = [-1, 0, 1, 0]
# 1.토네이도 회전 방향(y위치)
dict = {0: left, 1: down, 2: right, 3: up}
time = 0
for i in range(2*N-1):
# 몫: i//4(타임+1), 나머지:i%4(방향)
d = i % 4
if d == 0 or d == 2: # 다음 회차(d==0) 이거나 right(d==2) 이면 한번 더
time += 1
for _ in range(time):
n_x = s_x + dx[d]
n_y = s_y + dy[d]
recount(n_x, n_y, dict[d]) # y좌표, 방향
s_x, s_y = n_x, n_y
print(ans)
'PS' 카테고리의 다른 글
스타트 택시 [삼성 기출] (0) | 2023.10.07 |
---|---|
청소년 상어 [삼성 기출] (1) | 2023.10.06 |
양과 늑대 [2022 KAKAO BLIND RECRUITMENT] (1) | 2023.10.04 |
후보키 2 [2019 KAKAO BLIND RECRUITMENT] (1) | 2023.10.04 |
양궁대회 2 [2022 KAKAO BLIND RECRUITMENT] (1) | 2023.10.04 |