본문 바로가기

코딩테스트/파이썬

백준 12100번 2048(Easy)

728x90

문제 설명

 

max_block은 가장 큰 블록을 뜻하고 count는 이동한 횟수를 뜻한다. 이동한 횟수가 5번이면 해당 블록에서 가장 큰 값과 max_block을 비교한다.

 

goUp함수는 위로 블록을 이동시키는 함수다. copy_board는 위로 이동한 블록의 결과값을 저장한다. goUp함수는 첫번째 열부터 마지막 열까지 반복문을 돌린다. 반복문의 순서는

1. 해당 열에서 0보다 큰 값이 있으면 해당 열의 index를 tmp 배열에 담는다.

2-1. tmp 배열의 길이가 1일 경우 copy_board에 해당 열의 첫번째 행에 값을 대입한다.

2-2. tmp 배열의 길이가 1보다 클 경우 tmp에서 index를 2개씩 빼서 블록값을 비교 후 값이 같으면 results 배열에 담고 같지 않으면 나중에 뺀 index를 다시 tmp에 넣고 첫번째로 뺀 index의 블록값을 results에 넣는다.

3. results 배열에서 값을 하나씩 빼서 순서대로 copy_board에 해당 열의 첫번째 행부터 넣는다.

 

 

중간에 if len(tmp) == 1은 합쳐지지 않은 블록이 존재할 경우 마지막에 tmp 배열에는 값이 하나만 남게 된다. (예를 들어, tmp=[2,2,8] 이거나 tmp=[2,4,8] 같은 경우)

 

오른쪽,아래쪽,왼쪽 모두 해당 원리로 index 값들만 수정하여 코드를 작성했다.

 

전체 코드

board = []
max_block = 0
N = 0

def goLeft(arr):
    copy_board = [[0] * N for _ in range(N)]
    for i in range(N):
        tmp = []
        for j in range(N):
            if arr[i][j] > 0:
                tmp.append(j)
        if len(tmp) == 1:
            num = tmp[0]
            copy_board[i][0] = arr[i][num]
        elif len(tmp) > 1:
            results = []
            while tmp:
                if len(tmp) == 1:
                    break
                num1 = tmp.pop(0)
                num2 = tmp.pop(0)
                if arr[i][num1] == arr[i][num2]:
                    results.append(arr[i][num1] + arr[i][num2])
                else:
                    tmp.insert(0, num2)
                    results.append(arr[i][num1])
            if len(tmp) == 1:
                num1 = tmp.pop(0)
                results.append(arr[i][num1])
            k = 0
            while results:
                copy_board[i][k] = results.pop(0)
                k += 1
    return copy_board

def goDown(arr):
    copy_board = [[0] * N for _ in range(N)]
    for j in range(N):
        tmp = []
        for i in reversed(range(N)):
            if arr[i][j] > 0:
                tmp.append(i)
        if len(tmp) == 1:
            num = tmp[0]
            copy_board[N-1][j] = arr[num][j]
        elif len(tmp) > 1:
            results = []
            while tmp:
                if len(tmp) == 1:
                    break
                num1 = tmp.pop(0)
                num2 = tmp.pop(0)
                if arr[num1][j] == arr[num2][j]:
                    results.append(arr[num1][j] + arr[num2][j])
                else:
                    tmp.insert(0, num2)
                    results.append(arr[num1][j])
            if len(tmp) == 1:
                num1 = tmp.pop(0)
                results.append(arr[num1][j])
            k = N-1
            while results:
                copy_board[k][j] = results.pop(0)
                k -= 1
    return copy_board

def goRight(arr):
    copy_board = [[0] * N for _ in range(N)]
    for i in range(N):
        tmp = []
        for j in reversed(range(N)):
            if arr[i][j] > 0:
                tmp.append(j)
        if len(tmp) == 1:
            num = tmp[0]
            copy_board[i][N-1] = arr[i][num]
        elif len(tmp) > 1:
            results = []
            while tmp:
                if len(tmp) == 1:
                    break
                num1 = tmp.pop(0)
                num2 = tmp.pop(0)
                if arr[i][num1] == arr[i][num2]:
                    results.append(arr[i][num1] + arr[i][num2])
                else:
                    tmp.insert(0, num2)
                    results.append(arr[i][num1])
            if len(tmp) == 1:
                num1 = tmp.pop(0)
                results.append(arr[i][num1])
            k = N - 1
            while results:
                copy_board[i][k] = results.pop(0)
                k -= 1
    return copy_board

def goUp(arr):
    copy_board = [[0] * N for _ in range(N)]
    for j in range(N):
        tmp = []
        for i in range(N):
            if arr[i][j] > 0:
                tmp.append(i)
        if len(tmp) == 1:
            num = tmp[0]
            copy_board[0][j] = arr[num][j]
        elif len(tmp) > 1:
            results = []
            while tmp:
                if len(tmp) == 1:
                    break
                num1 = tmp.pop(0)
                num2 = tmp.pop(0)
                if arr[num1][j] == arr[num2][j]:
                    results.append(arr[num1][j] + arr[num2][j])
                else:
                    tmp.insert(0, num2)
                    results.append(arr[num1][j])
            if len(tmp) == 1:
                num1 = tmp.pop(0)
                results.append(arr[num1][j])
            k = 0
            while results:
                copy_board[k][j] = results.pop(0)
                k += 1
    return copy_board

def func(arr,count):
    global max_block
    if count == 5:
        for i in range(N):
            for j in range(N):
                if arr[i][j] > max_block:
                    max_block = arr[i][j]
        return

    func(goUp(arr),count+1)
    func(goRight(arr),count+1)
    func(goDown(arr),count+1)
    func(goLeft(arr),count+1)
    return

def main():
    global N
    global board
    N = int(input())
    board = [list(map(int,input().split())) for _ in range(N)]
    func(board,0)
    print(max_block)
    return

if __name__ == "__main__":
    main()
728x90
반응형

'코딩테스트 > 파이썬' 카테고리의 다른 글

백준 11559번 Puyo Puyo  (0) 2021.02.09
백준 18808번 스티커 붙이기  (0) 2021.02.09
백준 15683번 감시  (0) 2021.02.06
백준 1799번 비숍  (0) 2021.02.04
백준 1182번 부분수열의 합  (0) 2021.02.03