728x90
21608번: 상어 초등학교
상어 초등학교에는 교실이 하나 있고, 교실은 N×N 크기의 격자로 나타낼 수 있다. 학교에 다니는 학생의 수는 N2명이다. 오늘은 모든 학생의 자리를 정하는 날이다. 학생은 1번부터 N2번까지 번호
www.acmicpc.net
🤔 문제분석
문제만 잘 이해하고 접근했다면 쉽게 풀 수 있는 문제이다. 조건에 따라서 첫번째 연산까지만 할지 두번째 연산까지만 할지 세번째 연산까지만 할지 분기시킨다. 필자는 첫번째 연산, 두번째 연산이 배열의 길이가 1 초과인경우 연산을 추가로 할것인지 분기를 시켰다. 그리고 각 조건에 맞는 결과를 얻기위해 딕셔너리를 사용하였고 딕셔너리를 배열로 전환한뒤 주어진 조건에 따라서 정렬해서 문제를 해결하였습니다.
💻 코드
import sys
from collections import defaultdict
input = sys.stdin.readline
N = int(input())
student_like = [set() for _ in range(N*N + 1)]
order_student = []
for _ in range(N*N):
temp = list(map(int, input().split()))
order_student.append(temp[0])
for t in temp[1:]:
student_like[temp[0]].add(t)
room = [[0 for _ in range(N)] for _ in range(N)]
def is_near_by(y1, x1, y2, x2):
return 1 == (abs(y1-y2) + abs(x1-x2))
def get_bigest(near_dict):
temp = []
for key in near_dict:
temp.append((near_dict[key], key[0], key[1]))
temp.sort(reverse=True)
result = []
for t in temp:
if temp[0][0] != t[0]:
break
if room[t[1]][t[2]] == 0:
result.append((t[1], t[2]))
return result
def first(likedstudent):
queue = []
near_dict = defaultdict(int)
# 내가 좋아하는 학생찾기
for i in range(N):
for j in range(N):
near_dict[(i, j)] = 0
if room[i][j] in likedstudent:
queue.append((i, j))
# 가장 인접한 칸 찾기
for i, j in queue:
for i1 in range(N):
for j1 in range(N):
if is_near_by(i, j, i1, j1) and room[i1][j1] == 0:
near_dict[(i1, j1)] += 1
return get_bigest(near_dict)
def second(queue):
near_dict = defaultdict(int)
for i, j in queue:
near_dict[(i, j)] = 0
for i1 in range(N):
for j1 in range(N):
if is_near_by(i, j, i1, j1) and room[i1][j1] == 0 and room[i][j] == 0:
near_dict[(i, j)] += 1
return get_bigest(near_dict)
def third(queue : list):
queue.sort(key=lambda x:(x[0], x[1]))
return [queue[0]]
for student in order_student:
queue = first(student_like[student])
if len(queue) > 1:
queue = second(queue)
if len(queue) > 1:
queue = third(queue)
seat_pos = queue[0]
room[seat_pos[0]][seat_pos[1]] = student
ans = 0
def get_score(like_cnt):
if like_cnt == 0:
return 0
elif like_cnt == 1:
return 1
elif like_cnt == 2:
return 10
elif like_cnt == 3:
return 100
else:
return 1000
for i in range(N):
for j in range(N):
student = room[i][j]
like_cnt = 0
for i1 in range(N):
for j1 in range(N):
if is_near_by(i, j, i1, j1) and room[i1][j1] in student_like[student]:
like_cnt += 1
ans += get_score(like_cnt)
print(ans)
🎯 피드백 및 개선사항
구현문제는 주어진 조건을 자세히 살펴보아야 처음에 문제를 어떻게 접근해야할지 보이는것 같습니다.
728x90
'알고리즘 > 백준' 카테고리의 다른 글
[백준] 1377번 : 버블소트 (1) | 2024.02.05 |
---|---|
[백준] 17140번 : 이차원 배열과 연산 (1) | 2024.02.04 |
[백준] 10800번 : 킬러볼 (0) | 2024.02.04 |
[백준] 4574번 : 스노미노쿠 (0) | 2024.02.04 |
[백준] 2933번 : 미네랄 (1) | 2024.01.31 |