https://www.acmicpc.net/problem/21608
21608번: 상어 초등학교
상어 초등학교에는 교실이 하나 있고, 교실은 N×N 크기의 격자로 나타낼 수 있다. 학교에 다니는 학생의 수는 N2명이다. 오늘은 모든 학생의 자리를 정하는 날이다. 학생은 1번부터 N2번까지 번호
www.acmicpc.net
# 21608 상어 초등학교
# 상 좌 하 우
dr = [-1, 0, 1, 0]
dc = [0, -1, 0, 1]
N = int(input())
likes = [list(map(int, input().split())) for _ in range(N ** 2)]
grounds = [[0] * N for _ in range(N)]
score_help = dict()
# 자리 구하기
for idx in range(N ** 2):
cur_likes = likes[idx]
cur_student = cur_likes.pop(0)
# 좋아하는 학생이 인접
# 빈 자리가 많아야
like_student = 0
empty_seat = 0
result_r = -1
result_c = -1
for r in range(N):
for c in range(N):
if grounds[r][c] == 0:
temp_student = 0
temp_empty = 0
for i in range(4):
cr = r + dr[i]
cc = c + dc[i]
if 0 <= cr < N and 0 <= cc < N:
if grounds[cr][cc] in cur_likes:
temp_student += 1
elif grounds[cr][cc] == 0:
temp_empty += 1
if temp_student > like_student:
like_student = temp_student
empty_seat = temp_empty
result_r = r
result_c = c
elif temp_student == like_student and temp_empty > empty_seat:
empty_seat = temp_empty
result_r = r
result_c = c
elif result_r == -1 and result_c == -1:
result_r = r
result_c = c
grounds[result_r][result_c] = cur_student
score_help[cur_student] = cur_likes
# score 구하기
result = 0
for r in range(N):
for c in range(N):
cnt = 0
for i in range(4):
cr = r + dr[i]
cc = c + dc[i]
if 0 <= cr < N and 0 <= cc < N and grounds[cr][cc] in score_help[grounds[r][c]]:
cnt += 1
if cnt == 0:
continue
cnt -= 1
result += (10 ** cnt)
print(result)
예전 풀이
# 21608 상어 초등학교
def make_seat(idx):
cur_student = students[idx][0]
favorite_friends = students[idx][1:]
maximum_cnt = 0
max_area_cnt = 0
my_r = -1
my_c = -1
for r in range(1, N + 1):
for c in range(1, N + 1):
friend_cnt = 0
area_cnt = 0
if seats[r][c] == 0:
if my_r == -1 and my_c == -1:
my_r = r
my_c = c
# 상
if r - 1 >= 1:
if seats[r - 1][c] == 0:
area_cnt += 1
if seats[r - 1][c] in favorite_friends:
friend_cnt += 1
# 좌
if c - 1 >= 1:
if seats[r][c - 1] == 0:
area_cnt += 1
if seats[r][c - 1] in favorite_friends:
friend_cnt += 1
# 하
if r + 1 <= N:
if seats[r + 1][c] == 0:
area_cnt += 1
if seats[r + 1][c] in favorite_friends:
friend_cnt += 1
# 우
if c + 1 <= N:
if seats[r][c + 1] == 0:
area_cnt += 1
if seats[r][c + 1] in favorite_friends:
friend_cnt += 1
# 친구 수가 많으면 갱신
if maximum_cnt < friend_cnt:
maximum_cnt = friend_cnt
max_area_cnt = area_cnt
my_r = r
my_c = c
elif maximum_cnt == friend_cnt and max_area_cnt < area_cnt:
max_area_cnt = area_cnt
my_r = r
my_c = c
# 자리 찾아서 return
seats[my_r][my_c] = cur_student
return
def get_score():
for r in range(1, N + 1):
for c in range(1, N + 1):
cnt = 0
cur_list = students[seats[r][c] - 1][1:]
# 위
if r - 1 >= 1 and seats[r - 1][c] > 0 and seats[r - 1][c] in cur_list:
cnt += 1
# 좌
if c - 1 >= 1 and seats[r][c - 1] > 0 and seats[r][c - 1] in cur_list:
cnt += 1
# 하
if r + 1 <= N and seats[r + 1][c] > 0 and seats[r + 1][c] in cur_list:
cnt += 1
# 우
if c + 1 <= N and seats[r][c + 1] > 0 and seats[r][c + 1] in cur_list:
cnt += 1
result[0] += score[cnt]
# 상 하 좌 우
dr = [-1, 1, 0, 0]
dc = [0, 0, -1, 1]
N = int(input())
students = [list(map(int, input().split())) for _ in range(N ** 2)]
seats = [[0] * (N + 2) for _ in range(N + 2)]
score = [0, 1, 10, 100, 1000]
result = [0]
for idx, student in enumerate(students):
make_seat(idx)
# 학생 정렬
students.sort()
# 점수 계산
get_score()
print(result[0])
'''
4
6 5 2 3 4
5 1 9 2 8
2 9 3 1 4
4 2 5 1 7
3 1 9 4 5
9 8 1 2 3
8 1 9 3 4
7 2 3 4 8
1 9 2 5 7
10 1 2 3 4
11 1 2 3 4
12 1 2 3 4
13 1 2 3 4
14 1 2 3 4
15 1 2 3 4
16 1 2 3 4
'''
'프로그래밍 > 문제풀이' 카테고리의 다른 글
[Python] 코드트리 2022-1 오전 예술성 (0) | 2022.10.14 |
---|---|
[Python] 백준 21609 상어 중학교 (0) | 2022.10.13 |
[Python] 백준 20057 마법사 상어와 토네이도 (0) | 2022.10.11 |
[Python] 코드트리 2022-1 오전 술래잡기 (0) | 2022.10.10 |
[Python] 백준 17143 낚시왕 (0) | 2022.10.09 |