πŸ“š Study/Baekjoon

[Gold V] 21608 - 상어 μ΄ˆλ“±ν•™κ΅

윰갱 2025. 4. 30. 14:22

문제

상어 μ΄ˆλ“±ν•™κ΅μ—λŠ” ꡐ싀이 ν•˜λ‚˜ 있고, ꡐ싀은 N×N 크기의 격자둜 λ‚˜νƒ€λ‚Ό 수 μžˆλ‹€. 학ꡐ에 λ‹€λ‹ˆλŠ” ν•™μƒμ˜ μˆ˜λŠ” N2λͺ…이닀. μ˜€λŠ˜μ€ λͺ¨λ“  ν•™μƒμ˜ 자리λ₯Ό μ •ν•˜λŠ” 날이닀. 학생은 1λ²ˆλΆ€ν„° N2λ²ˆκΉŒμ§€ λ²ˆν˜Έκ°€ 맀겨져 있고, (r, c)λŠ” rν–‰ c열을 μ˜λ―Έν•œλ‹€. κ΅μ‹€μ˜ κ°€μž₯ μ™Όμͺ½ μœ— 칸은 (1, 1)이고, κ°€μž₯ 였λ₯Έμͺ½ μ•„λž« 칸은 (N, N)이닀.

μ„ μƒλ‹˜μ€ ν•™μƒμ˜ μˆœμ„œλ₯Ό μ •ν–ˆκ³ , 각 학생이 μ’‹μ•„ν•˜λŠ” 학생 4λͺ…도 λͺ¨λ‘ μ‘°μ‚¬ν–ˆλ‹€. 이제 λ‹€μŒκ³Ό 같은 κ·œμΉ™μ„ μ΄μš©ν•΄ μ •ν•΄μ§„ μˆœμ„œλŒ€λ‘œ ν•™μƒμ˜ 자리λ₯Ό μ •ν•˜λ €κ³  ν•œλ‹€. ν•œ μΉΈμ—λŠ” 학생 ν•œ λͺ…μ˜ 자리만 μžˆμ„ 수 있고, |r1 - r2| + |c1 - c2| = 1을 λ§Œμ‘±ν•˜λŠ” 두 칸이 (r1, c1)κ³Ό (r2, c2)λ₯Ό μΈμ ‘ν•˜λ‹€κ³  ν•œλ‹€.

  1. λΉ„μ–΄μžˆλŠ” μΉΈ μ€‘μ—μ„œ μ’‹μ•„ν•˜λŠ” 학생이 μΈμ ‘ν•œ 칸에 κ°€μž₯ λ§Žμ€ 칸으둜 자리λ₯Ό μ •ν•œλ‹€.
  2. 1을 λ§Œμ‘±ν•˜λŠ” 칸이 μ—¬λŸ¬ 개이면, μΈμ ‘ν•œ μΉΈ μ€‘μ—μ„œ λΉ„μ–΄μžˆλŠ” 칸이 κ°€μž₯ λ§Žμ€ 칸으둜 자리λ₯Ό μ •ν•œλ‹€.
  3. 2λ₯Ό λ§Œμ‘±ν•˜λŠ” 칸도 μ—¬λŸ¬ 개인 κ²½μš°μ—λŠ” ν–‰μ˜ λ²ˆν˜Έκ°€ κ°€μž₯ μž‘μ€ 칸으둜, κ·ΈλŸ¬ν•œ 칸도 μ—¬λŸ¬ 개이면 μ—΄μ˜ λ²ˆν˜Έκ°€ κ°€μž₯ μž‘μ€ 칸으둜 자리λ₯Ό μ •ν•œλ‹€.

예λ₯Ό λ“€μ–΄, N = 3이고, 학생 N2λͺ…μ˜ μˆœμ„œμ™€ 각 학생이 μ’‹μ•„ν•˜λŠ” 학생이 λ‹€μŒκ³Ό 같은 경우λ₯Ό μƒκ°ν•΄λ³΄μž.

ν•™μƒμ˜ λ²ˆν˜Έμ’‹μ•„ν•˜λŠ” ν•™μƒμ˜ 번호
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
6 5, 2, 3, 4
5 1, 9, 2, 8
2 9, 3, 1, 4

κ°€μž₯ λ¨Όμ €, 4번 ν•™μƒμ˜ 자리λ₯Ό μ •ν•΄μ•Ό ν•œλ‹€. ν˜„μž¬ κ΅μ‹€μ˜ λͺ¨λ“  칸은 빈 칸이닀. 2번 쑰건에 μ˜ν•΄ μΈμ ‘ν•œ μΉΈ μ€‘μ—μ„œ λΉ„μ–΄μžˆλŠ” 칸이 κ°€μž₯ λ§Žμ€ 칸인 (2, 2)이 4번 ν•™μƒμ˜ μžλ¦¬κ°€ λœλ‹€.

     
  4  
     

λ‹€μŒ 학생은 3λ²ˆμ΄λ‹€. 1번 쑰건을 λ§Œμ‘±ν•˜λŠ” 칸은 (1, 2), (2, 1), (2, 3), (3, 2) 이닀. 이 칸은 λͺ¨λ‘ λΉ„μ–΄μžˆλŠ” μΈμ ‘ν•œ 칸이 2κ°œμ΄λ‹€. λ”°λΌμ„œ, 3번 쑰건에 μ˜ν•΄ (1, 2)κ°€ 3번 ν•™μƒμ˜ μžλ¦¬κ°€ λœλ‹€.

  3  
  4  
     

λ‹€μŒμ€ 9번 학생이닀. 9번 학생이 μ’‹μ•„ν•˜λŠ” ν•™μƒμ˜ λ²ˆν˜ΈλŠ” 8, 1, 2, 3이고, 이 쀑에 3은 μžλ¦¬μ— μ•‰μ•„μžˆλ‹€. μ’‹μ•„ν•˜λŠ” 학생이 κ°€μž₯ 많이 μΈμ ‘ν•œ 칸은 (1, 1), (1, 3)이닀. 두 μΉΈ λͺ¨λ‘ λΉ„μ–΄μžˆλŠ” μΈμ ‘ν•œ 칸이 1개이고, ν–‰μ˜ λ²ˆν˜Έλ„ 1이닀. λ”°λΌμ„œ, 3번 쑰건에 μ˜ν•΄ (1, 1)이 9번 ν•™μƒμ˜ μžλ¦¬κ°€ λœλ‹€.

9 3  
  4  
     

μ΄λ²ˆμ— 자리λ₯Ό μ •ν•  학생은 8번 학생이닀. (2, 1)이 8번 학생이 μ’‹μ•„ν•˜λŠ” 학생과 κ°€μž₯ 많이 μΈμ ‘ν•œ 칸이기 λ•Œλ¬Έμ—, μ—¬κΈ°κ°€ κ·Έ ν•™μƒμ˜ μžλ¦¬μ΄λ‹€.

9 3  
8 4  
     

7번 ν•™μƒμ˜ 자리λ₯Ό μ •ν•΄λ³΄μž. 1번 쑰건을 λ§Œμ‘±ν•˜λŠ” 칸은 (1, 3), (2, 3), (3, 1), (3, 2)둜 총 4κ°œκ°€ 있고, λΉ„μ–΄μžˆλŠ” μΉΈκ³Ό κ°€μž₯ 많이 μΈμ ‘ν•œ 칸은 (2, 3), (3, 2)이닀. ν–‰μ˜ λ²ˆν˜Έκ°€ μž‘μ€ (2, 3)이 7번 ν•™μƒμ˜ μžλ¦¬κ°€ λœλ‹€.

9 3  
8 4 7
     

μ΄λŸ°μ‹μœΌλ‘œ ν•™μƒμ˜ 자리λ₯Ό λͺ¨λ‘ μ •ν•˜λ©΄ λ‹€μŒκ³Ό κ°™λ‹€.

9 3 2
8 4 7
5 6 1

이제 ν•™μƒμ˜ λ§Œμ‘±λ„λ₯Ό ꡬ해야 ν•œλ‹€. ν•™μƒμ˜ λ§Œμ‘±λ„λŠ” 자리 λ°°μΉ˜κ°€ λͺ¨λ‘ λλ‚œ 후에 ꡬ할 수 μžˆλ‹€. ν•™μƒμ˜ λ§Œμ‘±λ„λ₯Ό κ΅¬ν•˜λ €λ©΄ κ·Έ 학생과 μΈμ ‘ν•œ 칸에 앉은 μ’‹μ•„ν•˜λŠ” ν•™μƒμ˜ 수λ₯Ό ꡬ해야 ν•œλ‹€. κ·Έ 값이 0이면 ν•™μƒμ˜ λ§Œμ‘±λ„λŠ” 0, 1이면 1, 2이면 10, 3이면 100, 4이면 1000이닀.

ν•™μƒμ˜ λ§Œμ‘±λ„μ˜ 총 합을 κ΅¬ν•΄λ³΄μž.

μž…λ ₯

첫째 쀄에 N이 μ£Όμ–΄μ§„λ‹€. λ‘˜μ§Έ 쀄뢀터 N2개의 쀄에 ν•™μƒμ˜ λ²ˆν˜Έμ™€ κ·Έ 학생이 μ’‹μ•„ν•˜λŠ” 학생 4λͺ…μ˜ λ²ˆν˜Έκ°€ ν•œ 쀄에 ν•˜λ‚˜μ”© μ„ μƒλ‹˜μ΄ 자리λ₯Ό μ •ν•  μˆœμ„œλŒ€λ‘œ μ£Όμ–΄μ§„λ‹€.

ν•™μƒμ˜ λ²ˆν˜ΈλŠ” μ€‘λ³΅λ˜μ§€ μ•ŠμœΌλ©°, μ–΄λ–€ 학생이 μ’‹μ•„ν•˜λŠ” 학생 4λͺ…은 λͺ¨λ‘ λ‹€λ₯Έ ν•™μƒμœΌλ‘œ 이루어져 μžˆλ‹€. μž…λ ₯으둜 μ£Όμ–΄μ§€λŠ” ν•™μƒμ˜ 번호, μ’‹μ•„ν•˜λŠ” ν•™μƒμ˜ λ²ˆν˜ΈλŠ” N2보닀 μž‘κ±°λ‚˜ 같은 μžμ—°μˆ˜μ΄λ‹€. μ–΄λ–€ 학생이 자기 μžμ‹ μ„ μ’‹μ•„ν•˜λŠ” κ²½μš°λŠ” μ—†λ‹€.

좜λ ₯

첫째 쀄에 ν•™μƒμ˜ λ§Œμ‘±λ„μ˜ 총 합을 좜λ ₯ν•œλ‹€.

μ œν•œ

  • 3 ≤ N ≤ 20

예제 μž…λ ₯ 1 λ³΅μ‚¬

3
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
6 5 2 3 4
5 1 9 2 8
2 9 3 1 4

예제 좜λ ₯ 1 λ³΅μ‚¬

54

예제 μž…λ ₯ 2 λ³΅μ‚¬

3
4 2 5 1 7
2 1 9 4 5
5 8 1 4 3
1 2 9 3 4
7 2 3 4 8
9 8 4 5 7
6 5 2 3 4
8 4 9 2 1
3 9 2 1 4

예제 좜λ ₯ 2 λ³΅μ‚¬

1053

# 풀이 방법

개인적으둜 μ‹œκ°„μ΄ λ„ˆλ¬΄ 였래 κ±Έλ Έλ‹€. 1μ‹œκ°„ 이상이 κ±Έλ ΈμœΌλ‹ˆ κ΅¬ν˜„μ„ 슀슀둜 ν•΄λ‚΄κΈ°λŠ” ν–ˆμ§€λ§Œ μ΅œμ ν™”κΉŒμ§€λŠ” μ‹€νŒ¨ν–ˆλ‹€

 

일단 쑰건1>쑰건2>쑰건3 순으둜 μ½”λ“œλ₯Ό κ΅¬ν˜„ν–ˆλ‹€.

쑰건1) λΉ„μ–΄μžˆλŠ” 곡간을 κΈ°μ€€μœΌλ‘œ μ£Όλ³€μ˜ μ’‹μ•„ν•˜λŠ” 학생 수λ₯Ό μ…Œκ³ 

쑰건2) 쑰건1에 μ˜ν•΄ κ±ΈλŸ¬μ§„ μœ„μΉ˜λ₯Ό κΈ°μ€€μœΌλ‘œ, 빈 자리 수λ₯Ό μ…Œκ³ 

쑰건3) 쑰건1,쑰건2에 μ˜ν•΄ κ±ΈλŸ¬μ§„ μœ„μΉ˜λ₯Ό κΈ°μ€€μœΌλ‘œ, sortedλ₯Ό μ΄μš©ν•΄μ„œ 행과열을 μž‘μ€κ±Έ μ„ νƒν•˜λ„λ‘ ν–ˆλ‹€.

 

ν—·κ°ˆλ Έλ˜ 뢀뢄은 scoreμ μˆ˜κ°€ max인게 μ—¬λŸ¬κ°œ μžˆμ„ λ•Œ μ–΄λ–»κ²Œ 같이 뽑아낼거냐. 필터링할거냐가 ν—·κ°ˆλ Έκ³ 

λ¦¬μŠ€νŠΈμ— score μ μˆ˜κΉŒμ§€ ν•¨κ»˜ μž‘μ•„ max인 score μ›μ†Œλ“€λ§Œ 뽑을 수 μžˆλ„λ‘ μ½”λ“œλ₯Ό κ΅¬ν˜„ν–ˆλ‹€.


# μ½”λ“œ

필터링을 μ’€ λ³΅μž‘ν•˜κ²Œ ν•œ 것 κ°™λ‹€..

# 2025-05-02 15:41-16:38
import sys
sys.stdin = open("input.txt","r")
n = int(sys.stdin.readline().strip())
students_fav_list = [list(map(int,sys.stdin.readline().split())) for _ in range(n*n)]
seats = [[0]*n for _ in range(n)]
position = []

dx = [-1,1,0,0]
dy = [0,0,-1,1]

def select_seat(fav_list):
    fav_empty_score = []

    for i in range(n):
        for j in range(n):
            fav_cnt = 0
            empty_cnt = 0
            if seats[i][j] == 0:
                for d in range(4):
                    nx, ny = i + dx[d], j + dy[d]
                    if 0 <= nx < n and 0 <= ny < n and seats[nx][ny] in fav_list:
                        fav_cnt += 1
                    if 0 <= nx < n and 0 <= ny < n and seats[nx][ny] == 0:
                        empty_cnt += 1
                fav_empty_score.append((i,j,fav_cnt,empty_cnt))
    
    # λΉ„μ–΄μžˆλŠ” μΉΈ μ€‘μ—μ„œ μ’‹μ•„ν•˜λŠ” 학생이 μΈμ ‘ν•œ 칸에 κ°€μž₯ λ§Žμ€ 칸으둜 자리λ₯Ό μ •ν•œλ‹€.
    max_fav = max(fav_empty_score, key = lambda x: x[2])[2]
    filtered1 = [s for s in fav_empty_score if s[2] == max_fav]
    if len(filtered1) == 1:
        return (filtered1[0][0],filtered1[0][1])
    
    # 1을 λ§Œμ‘±ν•˜λŠ” 칸이 μ—¬λŸ¬ 개이면, μΈμ ‘ν•œ μΉΈ μ€‘μ—μ„œ λΉ„μ–΄μžˆλŠ” 칸이 κ°€μž₯ λ§Žμ€ 칸으둜 자리λ₯Ό μ •ν•œλ‹€.
    max_empty = max(filtered1, key = lambda x: x[3])[3]
    filtered2 = [s for s in filtered1 if s[3] == max_empty]
    if len(filtered2) == 1:
        return (filtered2[0][0],filtered2[0][1])
    
    filtered3 = sorted(filtered2)
    return (filtered3[0][0],filtered3[0][1])

def cal_score(position_list, fav_list):
    score_list = [0,1,10,100,1000]
    cnt = 0
    i, j = position_list
    for d in range(4):
        nx, ny = i + dx[d], j + dy[d]
        if 0 <= nx < n and 0 <= ny < n and seats[nx][ny] in fav_list:
            cnt += 1
    return score_list[cnt]
                    
for i in range(n*n):
    x, y = select_seat(students_fav_list[i][1:])
    position.append((x,y))
    seats[x][y] = students_fav_list[i][0]
    
total_score = 0
for i in range(n*n):
    score = cal_score(position[i],students_fav_list[i][1:])
    total_score += score
print(total_score)

 

 

gptκ°€ μ΅œμ ν™”ν•΄μ€€ μ½”λ“œ (쑰건1,쑰건2,쑰건3λ₯Ό ν•˜λ‚˜μ˜ ν•¨μˆ˜λ‘œ)

import sys
sys.stdin = open("input.txt", "r")

n = int(sys.stdin.readline())
students = []
like_map = dict()

for _ in range(n * n):
    data = list(map(int, sys.stdin.readline().split()))
    students.append(data[0])
    like_map[data[0]] = set(data[1:])

dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
result = [[0] * n for _ in range(n)]
student_pos = dict()

def get_best_position(student):
    max_like, max_empty = -1, -1
    candidates = []

    for i in range(n):
        for j in range(n):
            if result[i][j] != 0:
                continue
            like, empty = 0, 0
            for d in range(4):
                nx, ny = i + dx[d], j + dy[d]
                if 0 <= nx < n and 0 <= ny < n:
                    if result[nx][ny] in like_map[student]:
                        like += 1
                    elif result[nx][ny] == 0:
                        empty += 1
            if like > max_like or (like == max_like and empty > max_empty):
                candidates = [(i, j)]
                max_like, max_empty = like, empty
            elif like == max_like and empty == max_empty:
                candidates.append((i, j))
    
    # 쑰건 3: ν–‰, μ—΄ κΈ°μ€€ μ •λ ¬
    candidates.sort()
    return candidates[0]

def calculate_satisfaction():
    score_table = [0, 1, 10, 100, 1000]
    total = 0
    for student in students:
        x, y = student_pos[student]
        like = 0
        for d in range(4):
            nx, ny = x + dx[d], y + dy[d]
            if 0 <= nx < n and 0 <= ny < n and result[nx][ny] in like_map[student]:
                like += 1
        total += score_table[like]
    return total

# 자리 배치
for student in students:
    x, y = get_best_position(student)
    result[x][y] = student
    student_pos[student] = (x, y)

# λ§Œμ‘±λ„ 좜λ ₯
print(calculate_satisfaction())

# μ°Έκ³  (μ΅œμ ν™”ν•˜μ§€ λͺ»ν•œ μ½”λ“œ)

λ‚΄ 힘으둜 ν’€κΈ°λŠ” ν–ˆμœΌλ‚˜ μ°Έ 였래 κ±Έλ Έλ‹€.. 쀑간쀑간 ν—·κ°ˆλ¦¬λŠ” 파이썬 문법도 찾기도 ν–ˆκ³ 

# 2025-04-30 12:37-13:50
import sys
sys.stdin = open("input.txt","r")

n = int(sys.stdin.readline().strip())
students = []
for i in range(n*n):
    tmp_list = list(map(int,sys.stdin.readline().split()))
    students.append(tmp_list)

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

dx = [-1,1,0,0]
dy = [0,0,-1,1]

# 쑰건 1 --- λΉ„μ–΄μžˆλŠ” μΉΈ μ€‘μ—μ„œ μ’‹μ•„ν•˜λŠ” 학생이 μΈμ ‘ν•œ 칸에 κ°€μž₯ λ§Žμ€ μΉΈ
def cond1(fav_list):
    scores = []
    for i in range(n):
        for j in range(n):
            if result[i][j] == 0:
                cnt = 0
                for k in range(4):
                    nx, ny = i + dx[k], j + dy[k]
                    if 0 <= nx < n and 0 <= ny < n:
                        if result[nx][ny] in fav_list:
                            cnt += 1
                scores.append((i,j,cnt))
    max_val = max(scores,key=lambda x:x[2])[2]
    filtered = [(s[0],s[1]) for s in scores if s[2] == max_val]
    return filtered

# 쑰건 2 --- 1을 λ§Œμ‘±ν•˜λŠ” 칸이 μ—¬λŸ¬ 개이면, μΈμ ‘ν•œ μΉΈ μ€‘μ—μ„œ λΉ„μ–΄μžˆλŠ” 칸이 κ°€μž₯ λ§Žμ€ μΉΈ
def cond2(filtered):
    scores = []
    for f in filtered:
        x, y = f
        cnt = 0
        for i in range(4):
            nx, ny = x + dx[i], y + dy[i]
            if 0 <= nx < n and 0 <= ny < n:
                if result[nx][ny] == 0:
                    cnt += 1
        scores.append((x,y,cnt))
    max_val = max(scores,key=lambda x:x[2])[2]
    filtered2 = [(s[0],s[1]) for s in scores if s[2] == max_val]

    return filtered2

def cal_result(student, fav_list):
    for i in range(n):
        for j in range(n):
            if result[i][j] == student:
                cnt = 0
                for k in range(4):
                    nx, ny = i + dx[k], j + dy[k]
                    if 0 <= nx < n and 0 <= ny < n:
                        if result[nx][ny] in fav_list:
                            cnt += 1             
                if cnt == 0: return 0
                elif cnt == 1: return 1
                elif cnt == 2: return 10
                elif cnt == 3: return 100
                elif cnt == 4: return 1000

for i in range(n*n):
    filtered = cond1(students[i][1:])
    if len(filtered) == 1:
        result[filtered[0][0]][filtered[0][1]] = students[i][0]
        continue
    filtered2 = cond2(filtered)
    if len(filtered2) == 1:
        result[filtered2[0][0]][filtered2[0][1]] = students[i][0]
        continue
    # 쑰건 3 --- 2λ₯Ό λ§Œμ‘±ν•˜λŠ” 칸도 μ—¬λŸ¬ 개인 κ²½μš°μ—λŠ” ν–‰μ˜ λ²ˆν˜Έκ°€ κ°€μž₯ μž‘μ€ 칸으둜, κ·ΈλŸ¬ν•œ 칸도 μ—¬λŸ¬ 개이면 μ—΄μ˜ λ²ˆν˜Έκ°€ κ°€μž₯ μž‘μ€ 칸으둜
    sorted_filtered2 = sorted(filtered2,key=lambda x:(x[0],x[1]))
    result[sorted_filtered2[0][0]][sorted_filtered2[0][1]] = students[i][0]

final_score = 0
for i in range(n*n):
    final_score += cal_result(students[i][0],students[i][1:])
print(final_score)

'πŸ“š Study > Baekjoon' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

[Silver II] 12933 - 였리  (0) 2025.05.04
[Silver I] 1283 - 단좕킀 μ§€μ •  (0) 2025.05.01
[Gold V] 16926 - λ°°μ—΄ 돌리기1  (0) 2025.04.27
[Gold IV] 1107 - 리λͺ¨μ»¨  (0) 2025.04.25
[Gold IV] 14502 - μ—°κ΅¬μ†Œ  (0) 2025.04.25