λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

Algorithm/BOJ

[λ°±μ€€] 3085. 사탕 κ²Œμž„

 

πŸ“ͺ [사탕 κ²Œμž„]

 

 

3085번: 사탕 κ²Œμž„

예제 3의 경우 4번 ν–‰μ˜ Y와 Cλ₯Ό λ°”κΎΈλ©΄ 사탕 λ„€ 개λ₯Ό 먹을 수 μžˆλ‹€.

www.acmicpc.net


 

 

πŸ“‹ λ¬Έμ œμ„€λͺ…

μƒκ·Όμ΄λŠ” 어렸을 적에 "λ΄„λ³΄λ‹ˆ (Bomboni)" κ²Œμž„μ„ μ¦κ²¨ν–ˆλ‹€.

κ°€μž₯ μ²˜μŒμ— N×N크기에 사탕을 μ±„μ›Œ λ†“λŠ”λ‹€. μ‚¬νƒ•μ˜ 색은 λͺ¨λ‘ κ°™μ§€ μ•Šμ„ μˆ˜λ„ μžˆλ‹€.

μƒκ·Όμ΄λŠ” μ‚¬νƒ•μ˜ 색이 λ‹€λ₯Έ μΈμ ‘ν•œ 두 칸을 κ³ λ₯Έλ‹€. κ·Έ λ‹€μŒ κ³ λ₯Έ 칸에 λ“€μ–΄μžˆλŠ” 사탕을 μ„œλ‘œ κ΅ν™˜ν•œλ‹€.

이제, λͺ¨λ‘ 같은 μƒ‰μœΌλ‘œ 이루어져 μžˆλŠ” κ°€μž₯ κΈ΄ 연속 λΆ€λΆ„(ν–‰ λ˜λŠ” μ—΄)을 κ³ λ₯Έ λ‹€μŒ κ·Έ 사탕을 λͺ¨λ‘ λ¨ΉλŠ”λ‹€.

사탕이 μ±„μ›Œμ§„ μƒνƒœκ°€ μ£Όμ–΄μ‘Œμ„ λ•Œ, 상근이가 먹을 수 μžˆλŠ” μ‚¬νƒ•μ˜ μ΅œλŒ€ 개수λ₯Ό κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.

 

 

 

πŸ‘‍πŸ—¨ μž…μΆœλ ₯ 데이터

[μž…λ ₯]

첫째 쀄에 λ³΄λ“œμ˜ 크기 N이 μ£Όμ–΄μ§„λ‹€. (3 ≤ N ≤ 50)

λ‹€μŒ N개 μ€„μ—λŠ” λ³΄λ“œμ— μ±„μ›Œμ Έ μžˆλŠ” μ‚¬νƒ•μ˜ 색상이 μ£Όμ–΄μ§„λ‹€.

빨간색은 C, νŒŒλž€μƒ‰μ€ P, μ΄ˆλ‘μƒ‰μ€ Z, λ…Έλž€μƒ‰μ€ Y둜 μ£Όμ–΄μ§„λ‹€.

μ‚¬νƒ•μ˜ 색이 λ‹€λ₯Έ μΈμ ‘ν•œ 두 칸이 μ‘΄μž¬ν•˜λŠ” μž…λ ₯만 μ£Όμ–΄μ§„λ‹€.

3
CCP
CCP
PPC

[좜λ ₯]

첫째 쀄에 상근이가 먹을 수 μžˆλŠ” μ‚¬νƒ•μ˜ μ΅œλŒ€ 개수λ₯Ό 좜λ ₯ν•œλ‹€.

3

 

 

 

 

πŸ”‘ λ¬Έμ œν’€μ΄

문제 μ΄ν•΄ν•˜κΈ°

ν•΄λ‹Ή λ¬Έμ œλŠ” λͺ¨λ“  경우의 수λ₯Ό κ³ λ €ν•΄μ•Ό ν•˜λŠ” '브루트포슀 (Brute Force)', 완전탐색 문제둜 λ‹€μŒμ˜ 두 과정을 톡해 닡을 λ„μΆœν•  수 μžˆλ‹€.

 

1. μΈμ ‘ν•œ 두 사탕을 κ΅ν™˜ν•œλ‹€. (단, 2번 ν›„ μ›μœ„μΉ˜λ‘œ 볡ꡬ할 것)

2. κ°€μž₯ κΈ΄ 연속뢀뢄(ν–‰ λ˜λŠ” μ—΄)을 κ΅¬ν•œλ‹€.

 

μ΄λ•Œ NxN으둜 2차원 λ°°μ—΄μ΄λ―€λ‘œ 이쀑 for문의 0λΆ€ν„° nκΉŒμ§€μ˜ λ°˜λ³΅μ„ 톡해 κ΅ν™˜κ³Ό 탐색을 μ§„ν–‰ν•΄μ•Ό ν•œλ‹€. (O(N^2))

λ”°λΌμ„œ κ΅ν™˜(1)κ³Ό 탐색(2) λͺ¨λ‘ μ‹œκ°„λ³΅μž‘λ„ O(N^2)을 κ°€μ§€λ―€λ‘œ 전체 μ‹œκ°„λ³΅μž‘λ„λŠ” O(N^4)이닀.

ν—ˆλ‚˜ κ΅ν™˜ 및 νƒμƒ‰μ‹œ μƒν•˜μ’Œμš° λ°©ν–₯을 λͺ¨λ‘ κ³ λ €ν•΄μ•Όν•œλ‹€κ³  착각할 수 μžˆμ§€λ§Œ μ΄λŠ” μ€‘λ³΅μ˜ 경우λ₯Ό ν¬ν•¨ν•˜κΈ°μ— '우'와 'ν•˜'의 쑰건으둜만 ν•΄λ‹Ήμ‹œμΌœλ„ μΆ©λΆ„ν•˜λ‹€. 이λ₯Ό μ΄μš©ν•œ ν•΄λ‹Ή ν’€μ΄μ˜ μ½”λ“œλŠ” μ•„λž˜μ™€ κ°™λ‹€. 

 

def search_max_candy(n, candy_l):  # κ³ μ •λœ 상황. μ΅œλŒ€ μΊ”λ”” 수만 μ„ΈκΈ°.
    count_max_row = 1
    count_max_col = 1
    for x in range(n):
        count_row = 1
        count_col = 1
        for y in range(n - 1):
            if candy_l[x][y] == candy_l[x][y + 1]:  # '우'와 동일 μ—¬λΆ€ 비ꡐ.(row) (μ„Έλ‘œ λ§ˆμ§€λ§‰ μ—΄ 배제)
                count_row += 1
                if count_max_row < count_row:
                    count_max_row = count_row
            else:
                count_row = 1
            if candy_l[y][x] == candy_l[y+1][x]:  # 'ν•˜'와 동일 μ—¬λΆ€ 비ꡐ.(col) (κ°€λ‘œ λ§ˆμ§€λ§‰ ν–‰ 배제)
                count_col += 1
                if count_max_col < count_col:
                    count_max_col = count_col
            else:
                count_col = 1
    return max(count_max_row, count_max_col)


input_n = int(input())
candy_list = [list(input()) for _ in range(input_n)]
count_ans = 0
for i in range(input_n):
    for j in range(input_n):
        # '우'와 'ν•˜'의 경우만 κ³ λ € - μΈμ ‘ν•œ 사탕을 κ΅ν™˜
        if i + 1 < input_n :  # 'ν•˜'의 경우 - 행이 μ΅œλŒ€ 행일 경우, 'ν•˜' κ΅ν™˜ 성립 X. λ”°λΌμ„œ ν•΄λ‹Ή 경우 배제.
            candy_list[i][j], candy_list[i + 1][j] = candy_list[i + 1][j], candy_list[i][j]
            max_count = search_max_candy(input_n, candy_list)
            if max_count > count_ans:
                count_ans = max_count
            candy_list[i][j], candy_list[i + 1][j] = candy_list[i + 1][j], candy_list[i][j]
        if j + 1 < input_n :  # '우'의 경우 - 행이 μ΅œλŒ€ 행일 경우, '우' κ΅ν™˜ 성립 X. λ”°λΌμ„œ ν•΄λ‹Ή 경우 배제.
            candy_list[i][j], candy_list[i][j+1] = candy_list[i][j+1], candy_list[i][j]
            max_count = search_max_candy(input_n, candy_list)
            if max_count > count_ans:
                count_ans = max_count
            candy_list[i][j], candy_list[i][j+1] = candy_list[i][j+1], candy_list[i][j]

print(count_ans)

μœ„μ˜ ν’€μ΄μ˜ 경우 μƒν•˜μ’Œμš°μ—μ„œ '우'와 'ν•˜'둜 경우의 수λ₯Ό μ€„μ˜€μŒμ—λ„ 이쀑 for문을 λ‘λ²ˆ μ—°μ†ν•˜μ—¬ 콜 ν•˜λ―€λ‘œ 전체 μ‹œκ°„ λ³΅μž‘λ„μ˜ 경우 κ·ΈλŒ€λ‘œ 'O(N^4)'이닀. 😑

λ‹€ν–‰μŠ€λŸ½κ²Œλ„ N의 λ²”μœ„κ°€ 50μ΄ν•˜λ‘œ μž‘κΈ°μ—, μœ„μ˜ ν’€μ΄λ‘œ 풀어도 μ‹œκ°„ μ œν•œμ— μΆ©λΆ„ν•˜λ‹€.

ν—ˆλ‚˜ λ§Œμ•½ N의 λ²”μœ„κ°€ 500일 경우 N의 λ„€μ œκ³±μ€ 1얡을 λ„˜κΈ°μ— 1초 μ œν•œμ‹œκ°„μ— μ•„μ›ƒλ˜κ²Œ λœλ‹€.

κ·Έλ ‡λ‹€λ©΄ 이λ₯Ό μ–΄λ–»κ²Œ 더 효율적인 μ½”λ“œλ‘œ λ°”κΏ€ 수 μžˆμ„κΉŒ?

 

κ΅ν™˜ ν›„ νƒμƒ‰ν•˜λŠ” μ½”λ“œλ₯Ό 보면, 맀번 κ΅ν™˜ 이후 이쀑 for문을 톡해 λͺ¨λ“  NxN을 νƒμƒ‰ν•˜λŠ” 것을 μ•Œ 수 μžˆλ‹€. ν—ˆλ‚˜, 사싀 μž„μ˜μ˜ 두 칸을 λ³€κ²½ν•  경우 정닡에 λ³€ν™”κ°€ μžˆλŠ” 것은 μ΅œλŒ€ 3개의 ν–‰κ³Ό 열이기에 μ΄λŠ” 맀우 λΉ„νš¨μœ¨μ μ΄λ‹€. λ”°λΌμ„œ 이λ₯Ό κ³ λ €ν•˜μ—¬ μ•„λž˜μ™€ 같이 풀이λ₯Ό κ΅¬ν˜„ν•  수 μžˆλ‹€. 
// 이후 μ½”λ“œλŠ” μƒλž΅

 

 

 

 

 

 

 


 

 

 

 

πŸ”” 풀이/κ°œλ…μ •λ¦¬

  1. 이쀑 리슀트 μ»΄ν”„λ¦¬ν—¨μ…˜
    : 리슀트_λ„€μž„= [list(input()) for _ in range(N)]
  2. 파이썬 swap
    : a,b = b,a 
  3. (TIP) 2차원 λ°°μ—΄ λ“± λ°°μ—΄ 문제 → x(row), y(col) λ³€μˆ˜ κ³ μ •ν•˜κΈ°.

 

728x90