Preview
전형적인 시뮬레이션 문제이다. 때문에 문제에 제시된 조건들을 잘 따져가며 코딩하면 어렵지 않게 해결할 수 있다.
알고리즘
- 비어있는 칸 중에서 좋아하는 학생이 인접한 칸에 가장 많은 칸으로 자리를 정한다.
- 1을 만족하는 칸이 여러 개이면, 인접한 칸 중에서 비어있는 칸이 가장 많은 칸으로 자리를 정한다.
- 2를 만족하는 칸도 여러 개인 경우에는 행의 번호가 가장 작은 칸으로, 그러한 칸도 여러 개이면 열의 번호가 가장 작은 칸으로 자리를 정한다.
문제에서 제시한대로 만족도 > 빈칸 > 행 > 렬 순의 우선순위로 좌석을 찾아야 한다.
때문에 나의 코드는 다음과 같이 동작한다.
- 학생의 정보를 담은 리스트에서 한명씩 뽑아, 해당하는 학생을 문제의 조건에 맞는 위치에 자리시킨다.
- 위의 내용을 반복하여 모든 학생을 배치시킨 후 N*N행렬을 돌며 각 학생들의 만족도를 result 에 추가한다.
- result 를 출력한다.
함수설명
1. find_seat()
학생의 정보를 입력받아 위의 문제의 조건을 만족시키는 행, 열을 반환하는 함수.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def find_seat(info):
    max_count = -1
    vacant_count = -1
    r,c = 0,0
    
    for i in range(N):
        for j in range(N):
            if not classroom[i][j]:
                cnt, vacant_cnt = check(i,j,info)
                
                if cnt > max_count:
                    max_count = cnt
                    vacant_count = vacant_cnt
                    r,c = i,j
                    continue
                
                if cnt == max_count:
                    if vacant_cnt > vacant_count:
                        vacant_count = vacant_cnt
                        r,c = i,j
                    continue
    return r,c
2. check()
행,열, 학생의 정보를 입력받아 해당하는 위치 주변의 공석, 좋아하는 사람의 수 를 반환하는 함수.
1
2
3
4
5
6
7
8
9
10
11
12
13
def check(y,x,info):
    cnt = 0
    vacant_cnt = 0
    num, a,b,c,d = info
    for i in range(4):
        ny = y + dy[i]
        nx = x + dx[i]
        if 0 <= ny < N and 0 <= nx < N:
            if not classroom[ny][nx]:
                vacant_cnt += 1
            if classroom[ny][nx] == a or classroom[ny][nx] == b or classroom[ny][nx] == c or classroom[ny][nx] == d:
                cnt += 1
    return cnt, vacant_cnt
전체코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import sys
input = sys.stdin.readline
dy = [-1,0,1,0]
dx = [0,1,0,-1]
def check(y,x,info):
    cnt = 0
    vacant_cnt = 0
    num, a,b,c,d = info
    for i in range(4):
        ny = y + dy[i]
        nx = x + dx[i]
        if 0 <= ny < N and 0 <= nx < N:
            if not classroom[ny][nx]:
                vacant_cnt += 1
            if classroom[ny][nx] == a or classroom[ny][nx] == b or classroom[ny][nx] == c or classroom[ny][nx] == d:
                cnt += 1
    return cnt, vacant_cnt
def find_seat(info):
    max_count = -1
    vacant_count = -1
    r,c = 0,0
    
    for i in range(N):
        for j in range(N):
            if not classroom[i][j]:
                cnt, vacant_cnt = check(i,j,info)
                
                if cnt > max_count:
                    max_count = cnt
                    vacant_count = vacant_cnt
                    r,c = i,j
                    continue
                
                if cnt == max_count:
                    if vacant_cnt > vacant_count:
                        vacant_count = vacant_cnt
                        r,c = i,j
                    continue
    return r,c
N = int(input())
likes = [0] * (N*N)
classroom = [ [0] * N for _ in range(N)]
counts = [ [0] * N for _ in range(N)]
for i in range(N*N):
    s_num, a, b, c, d = map(int,input().split())
    likes[i] = (s_num,a,b,c,d)
for info in likes:
    r,c = find_seat(info)
    classroom[r][c] = info[0]
    counts[r][c] = [ item for item in info[1:]]
result = 0
for i in range(N):
    for j in range(N):
        count = 0 
        a,b,c,d = counts[i][j]
        for k in range(4):
            ny = i + dy[k]
            nx = j + dx[k]
            if 0<= ny < N and 0 <= nx < N:
                if classroom[ny][nx] == a or classroom[ny][nx] == b or classroom[ny][nx] == c or classroom[ny][nx] == d: 
                    count += 1
        
        if count > 0:
            result += 10 ** (count - 1)
print(result)
결과

