개발/algorithm

[백준 21608번] 상어 초등학교 - Python

zzi_on2 2022. 10. 4. 23:04

문제 링크

풀이 

완전 탐색 문제 

1. 학생을 자리에 배치할 때마다 graph를 완전 탐색하여 자리 별 인접한 칸의 좋아하는 학생 수와 빈칸 수를 구해서 heap에 삽입

2. heap에 (- 좋아하는 학생 수, - 빈칸 수, 행 번호, 열 번호) 를 삽입시켜줘서 조건에 맞는 자리 pop 

3. graph에 학생 번호 표시하고, sheet 에 학생 자리 위치를 기록

4. sheet을 통해 만족도 구하기 

# https://www.acmicpc.net/problem/21608
import heapq 
n = int(input())

order = []
student =  [ [] for _ in range(n**2 +1 )] 

for _ in range(n**2):
    a, b, c, d, e = map(int,input().split())
    # idx -> 학생 번호, 학생 별 좋아하는 
    student[a] = [b,c,d,e]
    # 자리 배치 순서 
    order.append(a)

graph = [[0] * n for _ in range(n)]

# 학생 별 자리 위치 저장 
sheet = [[] for _ in range(n**2 + 1)]
dx = [1,-1,0,0]
dy = [0,0,1,-1]

for num in order :
    q = []
    
    # 자리 별 인접한 칸의 좋아하는 사람 수와 빈칸 개수 heap에 삽입 
    for x in range(n):
        for y in range(n):
            cnt = 0 
            blank = 0
            # 이미 앉은 자리면 패스 
            if graph[x][y] :
                continue 
            
            for z in range(4):
                nx = x + dx[z]
                ny = y + dy[z]
                
                if nx < 0 or nx >= n or ny < 0 or ny >= n :
                    continue 
                if graph[nx][ny] in student[num]:
                    cnt += 1 
                if graph[nx][ny] == 0 :
                    blank +=1 
            
            heapq.heappush(q, (-cnt, -blank, x, y))
    
    tmp = heapq.heappop(q)
    
    # 학생 자리 표시 
    graph[tmp[2]][tmp[3]] = num
    # 학생 자리 위치 저장 
    sheet[num] = (tmp[2], tmp[3])
    
ans = 0 

# 만족도 구하기 
for i in range(1, n**2 + 1):
    x, y = sheet[i]
    cnt = 0 
    for j in range(4):
        nx = x + dx[j]
        ny = y + dy[j]
        
        if nx < 0 or nx >= n or ny < 0 or ny >= n :
            continue 
        
        if graph[nx][ny] in student[i]:
            cnt += 1
        
    if cnt == 0:
        continue 
    
    ans += 10**(cnt-1) 
        
print(ans)