[BaekJoon] 백준 21608번 상어 초등학교
🎈문제
https://www.acmicpc.net/problem/21608
💬설명
- 21년도 상반기 기출이었다. 그때 시험장에서 풀었었는데 준비가 안되어 있어서 제대로 풀지 못하고 헤맸던 것 같다. 지금 다시 풀어보니까 왜이렇게 쉬운 문제인지,,😢
- 시간을 재서 풀었더니 50분만에 풀었고, 한번에 솔브할 수 있었다.
- 문제를 보고 5가지 함수를 만들어줬다.
- solve(): 일종의 main 함수
- like_max(arr): 비어있는 칸 중 좋아하는 학생이 인접한 칸이 가장 많은 칸들의 배열을 반환해주는 함수
- empty_max(arr): 주어진 arr에서 인접한 칸 중 비어있는 칸이 가장 많은 칸(여러개일 수 있음) 배열을 반환해주는 함수
- smallest_position(arr): 주어진 arr에서 행이 가장 작은 (만약 같다면 열이 가장 작은) 칸을 반환해주는 함수
- cal_satisfy(): 만족도를 계산해서 반환해주는 함수
👩💻코드
# BaekJoon21608.py
# 초기값 설정
N = int(input())
positions = [[0 for _ in range(N)] for _ in range(N)]
likes = {}
dx = [1, -1, 0, 0]
dy = [0, 0, 1, -1]
for i in range(N * N):
arr = list(map(int, input().split()))
likes[arr[0]] = arr[1:]
# 좋아하는 학생이 인접한 칸에 가장 많은 칸 선택해서 return
def like_max(arr):
global positions, N, dx, dy
like_arr = {}
for x in range(N):
for y in range(N):
# 비어있지 않은 자리면 pass
if positions[x][y] != 0:
continue
like_student_num = 0
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
# 교실 밖으로 벗어난다면
if nx < 0 or ny < 0 or nx >= N or ny >= N:
continue
# 좋아하는 학생이 앉아있다면 +1
if positions[nx][ny] in arr:
like_student_num += 1
# 좋아하는 학생수 추가
if like_student_num in like_arr:
like_arr[like_student_num].append([x, y])
else:
like_arr[like_student_num] = [[x, y]]
# 좋아하는 학생 수가 최대인 자리 return
return like_arr[max(like_arr.keys())]
# 인접한 칸 중 비어있는 칸 가장 많은 칸 선택해서 return
def empty_max(arr):
global positions, N, dx, dy
empty_arr = {}
for x, y in arr:
empty_num = 0
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
# 교실 밖으로 벗어난다면
if nx < 0 or ny < 0 or nx >= N or ny >= N:
continue
if positions[nx][ny] == 0:
empty_num += 1
if empty_num in empty_arr:
empty_arr[empty_num].append([x, y])
else:
empty_arr[empty_num] = [[x, y]]
# 인접한 칸 중 비어있는 칸 가장 많은 자리 return
return empty_arr[max(empty_arr.keys())]
# 행이 가장 작은 칸 return. 만약 같다면 열이 가장 작은 칸 return
def smallest_position(arr):
return sorted(arr, key=lambda x: (x[0], x[1]))[0]
# 만족도 계산해서 return
def cal_satisfy():
global positions, likes, N, dx, dy
result = 0
for x in range(N):
for y in range(N):
student = positions[x][y]
like = 0
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
if nx < 0 or ny < 0 or nx >= N or ny >= N:
continue
if positions[nx][ny] in likes[student]:
like += 1
# 인접한 좋아하는 학생수에 따라 계산
if like == 1:
result += 1
elif like == 2:
result += 10
elif like == 3:
result += 100
elif like == 4:
result += 1000
return result
def solve():
global likes, positions
students = likes.keys()
for student in students:
like_max_list = like_max(likes[student])
if len(like_max_list) == 1:
selected = like_max_list[0]
else:
empty_max_list = empty_max(like_max_list)
if len(empty_max_list) == 1:
selected = empty_max_list[0]
else:
selected = smallest_position(empty_max_list)
positions[selected[0]][selected[1]] = student
print(cal_satisfy())
solve()
728x90
반응형
'CS > Algorithm 문제' 카테고리의 다른 글
[Programmers] 소수 찾기 (0) | 2021.10.14 |
---|---|
[Programmers] 모의고사 (0) | 2021.10.14 |
[Programmers] 가장 큰 수 (0) | 2021.10.13 |
[Programmers] H-Index (0) | 2021.10.13 |
[Programmers] K번째수 (0) | 2021.10.12 |