λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
⭐ Problem_Solving/λ°±μ€€

[λ°±μ€€] 12100 2048 (Easy) (Python/파이썬)

by ν¬μŠ€νŠΈμ‰μ΄ν¬ 2022. 10. 11.

<문제 링크>

https://www.acmicpc.net/problem/12100

 

12100번: 2048 (Easy)

첫째 쀄에 λ³΄λ“œμ˜ 크기 N (1 ≤ N ≤ 20)이 주어진닀. λ‘˜μ§Έ 쀄뢀터 N개의 μ€„μ—λŠ” κ²Œμž„νŒμ˜ 초기 μƒνƒœκ°€ 주어진닀. 0은 빈 칸을 λ‚˜νƒ€λ‚΄λ©°, μ΄μ™Έμ˜ 값은 λͺ¨λ‘ 블둝을 λ‚˜νƒ€λ‚Έλ‹€. 블둝에 μ“°μ—¬ μžˆλŠ” μˆ˜λŠ” 2

www.acmicpc.net

 

<풀이 μ „λž΅>

1. N이 20 μ΄ν•˜μ΄κ³  μ‹œν–‰μ΄ 5번으둜 κ³ μ •λ˜μ–΄ μžˆμ–΄μ„œ λ°±νŠΈλž˜ν‚Ήμ„ μ΄μš©ν•œ μ™„μ „νƒμƒ‰μœΌλ‘œ 문제λ₯Ό ν’€ 수 μžˆλ‹€.

2. λΈ”λŸ­μ˜ 병합 / 이동 2가지λ₯Ό μƒν•˜μ’Œμš° 4λ°©ν–₯으둜 κ΅¬ν˜„ν•΄μ•Όλ˜λŠ”λ° λ‚˜λŠ” ν•œ λ°©ν–₯에 λŒ€ν•΄μ„œλ§Œ κ΅¬ν˜„ν•˜κ³  λ‚˜λ¨Έμ§€λŠ” 배열을 νšŒμ „ μ‹œμΌœμ„œ μ μš©ν•˜λŠ” 법을 μ΄μš©ν–ˆλ‹€. (μ°Έκ³ : https://bluuubery.tistory.com/48?category=584396)

3. 쒌 -> 우 ν•œ λ°©ν–₯에 λŒ€ν•΄μ„œλ§Œ 이동과 병합을 κ΅¬ν˜„ν–ˆλŠ”λ° ν–‰ λ‹¨μœ„λ‘œ μ½”λ“œλ₯Ό μ§  덕뢄에 μŠ¬λΌμ΄μ‹± 등을 μ΄μš©ν•  수 μžˆμ–΄μ„œ 큰 어렀움은 μ—†μ—ˆλ‹€.

4. μ£Όμ˜ν•  점은 λΈ”λŸ­μ„ ν•©μΉ˜λŠ” κ³Όμ •μ—μ„œ 직전/직후 μ›μ†Œλž‘λ§Œ 비ꡐλ₯Ό ν•˜λ©΄ 2 0 0 2 -> 0 0 0 4 같은 경우λ₯Ό μ œλŒ€λ‘œ 확인을 λͺ»ν•˜λ―€λ‘œ 이동을 λ¨Όμ € ν•˜κ³  ν•©μ³μ€˜μ•Ό ν•œλ‹€.

 

<μ •λ‹΅ μ½”λ“œ>

import sys, os, io, atexit

input = lambda: sys.stdin.readline().rstrip('\r\n')
stdout = io.BytesIO()
sys.stdout.write = lambda s: stdout.write(s.encode("ascii"))
atexit.register(lambda: os.write(1, stdout.getvalue()))

# 221008 12100 2048(Easy)

# μ •λ‹΅μ½”λ“œ

# rotate: λ°°μ—΄ νšŒμ „ μ‹œν‚€λŠ” ν•¨μˆ˜ 
def rotate(d):
    global arr
    # μ‹œκ³„λ°©ν–₯ 0도
    if d == 0:
        return

    # μ‹œκ³„λ°©ν–₯ 90도
    elif d == 1:
        arr = list(map(list, zip(*arr[::-1])))
        return

    # μ‹œκ³„λ°©ν–₯ 180도
    elif d == 2:
        arr = [[arr[N - r - 1][N - c - 1] for c in range(N)] for r in range(N)]
        return

    # μ‹œκ³„λ°©ν–₯ 270도    
    else:
        arr = list(map(list, zip(*arr)))[::-1]
        return


# merge: λΈ”λŸ­λ“€μ„ ν•©μΉ˜λŠ” ν•¨μˆ˜ (ν–‰ λ‹¨μœ„)
def merge():
    
    for row in arr:
        for i in range(N - 1, 0, -1):
            # 직전 λΈ”λŸ­κ³Ό 같은 숫자일 경우
            if row[i] == row[i - 1]:
                # ν•΄λ‹Ή λΈ”λŸ­ *2, 직전 λΈ”λŸ­ 0
                row[i] *= 2
                row[i - 1] = 0


# move: λΈ”λŸ­λ“€μ„ ν•œ λ°©ν–₯으둜 λ°€μ–΄μ£ΌλŠ” ν•¨μˆ˜ (ν–‰ λ‹¨μœ„)
def move():

    for i in range(N):
        # new_row: ν•œ λ°©ν–₯으둜 λ°€λ¦° μƒˆλ‘œμš΄ ν–‰
        new_row = []
        # 0이 μ•„λ‹ˆλ©΄ new_row에 λ‹΄μ•„μ€€λ‹€.
        for j in range(N):
            if arr[i][j]:
                new_row.append(arr[i][j])

        # new_rowμ•žμ— 0을 뢙이고 μ›λž˜ ν–‰μ΄λž‘ λ°”κΏ”μ€€λ‹€. 
        arr[i] = [0] * (N - len(new_row)) + new_row


# λ°±νŠΈλž˜ν‚Ή ν•¨μˆ˜ 
def back_tracking(depth):
    global ans, arr

    # 5번 λ‹€ μ΄λ™ν–ˆμ„ λ•Œ μ΅œλŒ“κ°’ κ°±μ‹  ν›„ λ°˜ν™˜
    if depth == 5:
        ans = max(ans, max(map(max, arr)))
        return
    
    # μƒν•˜μ’Œμš° 4λ°©ν–₯으둜 λΈ”λŸ­ 이동
    for d in range(4):
        # arr_copy: λ°±νŠΈλž˜ν‚Ή μ‹œ μ›μƒνƒœ 볡원을 μœ„ν•œ 볡사본
        arr_copy = [arr[i][:] for i in range(N)]

        # 주어진 λ°©ν–₯으둜 λ°°μ—΄ νšŒμ „
        rotate(d)

        # 이동(ν•©μΉ˜κΈ° μœ„ν•œ μ „μ²˜λ¦¬) - ν•©μΉ˜κΈ° - 이동
        move()
        merge()
        move()

        # λ‹€μŒ μ‹œν–‰μœΌλ‘œ λ„˜μ–΄κ°„λ‹€.
        back_tracking(depth + 1)

        # λ°°μ—΄ μƒνƒœ 볡원
        arr = arr_copy


# N: λ°°μ—΄μ˜ 크기, arr: λ°°μ—΄ 초기 μƒνƒœ
N = int(input())
arr = [list(map(int, input().split())) for _ in range(N)]

# ans: λΈ”λŸ­μ˜ μ΅œλŒ“κ°’
ans = 0

# λ°±νŠΈλž˜ν‚Ή μ‹œν–‰
back_tracking(0)

# μ •λ‹΅ 좜λ ₯
print(ans)

 

λŒ“κΈ€