[코딩테스트][백준] 🔥 백준 20061번 "모노미노도미노 2" 문제: Python으로 완벽 해결하기! 🔥

김상욱·2024년 8월 31일
0
post-thumbnail

문제 링크

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

🕒 Python 풀이시간: 55분

import sys
import copy

input=sys.stdin.readline

def setXYBlock(t,x,y):
    if t==1:
        return [[x,y]]
    elif t==2:
        return [[x,y],[x,y+1]]
    elif t==3:
        return [[x,y],[x+1,y]]

def setBlock(posBlock):
    posBlock2=[]
    for x,y in posBlock:
        posBlock2.append([y,3-x])
    minB1,minB2=4,4
    for x,y in posBlock:
        minB1=min(minB1,x)
    for x,y in posBlock2:
        minB2=min(minB2,x)
    for i in range(len(posBlock)):
        posBlock[i][0]-=minB1
        posBlock2[i][0]-=minB2
    return [posBlock,posBlock2]

def goBlock(board,block):
    prev=copy.deepcopy(block)
    while True:
        for i in range(len(block)):
            block[i][0]+=1
        canPut=True
        for i in range(len(block)):
            if block[i][0]>=6 or board[block[i][0]][block[i][1]]==1:
                canPut=False
                break
        if canPut:
            prev=copy.deepcopy(block)
        else:
            break
    for i in range(len(prev)):
        board[prev[i][0]][prev[i][1]]=1
n=int(input())
board=[[[0]*4 for _ in range(6)] for _ in range(2)]

def getScore(board):
    global score
    new_board=[[0]*4 for _ in range(6)]
    fillIndex=5
    for i in range(5,-1,-1):
        full=True
        for j in range(4):
            if board[i][j]!=1:
                full=False
                break
        if full:
            score+=1
            continue
        for j in range(4):
            new_board[fillIndex][j]=board[i][j]
        fillIndex-=1
    return new_board

def deleteBlock(board):
    new_board=[[0]*4 for _ in range(6)]
    check=0
    for i in range(2):
        for j in range(4):
            if board[i][j]==1:
                check+=1
                break
    if check==0:
        return board
    fillIndex=5
    for i in range(5-check,-1,-1):
        for j in range(4):
            new_board[i+check][j]=board[i][j]
    return new_board

score=0

for _ in range(n):
    t,x,y=map(int,input().split())
    posBlock=setXYBlock(t,x,y)
    downBlocks=setBlock(posBlock)
    for i in range(2):
        goBlock(board[i],downBlocks[i])
        board[i]=getScore(board[i])
        board[i]=deleteBlock(board[i])

cnt=0
for i in range(2):
    for a in range(2,6):
        for b in range(4):
            if board[i][a][b]==1:
                cnt+=1
print(score)
print(cnt)

🧩 모노미노도미노: 블록의 대격돌!

모노미노도미노라는 게임이 진행되는 시뮬레이션을 풀어나가는 문제이다. 내려가는 블록과 오른쪽으로 가는 블록이 하나의 칸에 주어지면 그 방향대로 이동하면 된다.

결과적으로 하나의 칸에서 시작해서 2개의 방향으로 가긴 하지만 반대로 생각하면 출발 하는 블록 자체의 방향을 틀어버리면 같은 방향으로써 좌표를 처리할 수 있기 때문에 방향을 돌려서 내려가게 하도록 생각하였다. 배열을 2개 두고 블록을 먼저 좌표값을 가지고 배열의 회전을 이용하여 회전시킨다. 그런 다음, 그 회전된 블록이 0,1칸에 올 수 있도록 가장 작은 블록의 x좌표를 기준으로 맨 위로 붙여준다. 즉, 게임 시작을 한다면 0,1에서 부터 내려오도록 좌표를 조정해주는 것이다.

이렇게 블록이 조절이 완료가 되었다면 이제 내려오기만 하면 된다. 내려올 때에는, 다음 좌표값에 블록이 있는지 그리고 바닥인지만 확인하면서 내려와주면 된다. 그렇게 내려와주고 0,1을 확인하고 지우기 전에 점수를 먼저 구해야 하므로 각 열에 블록이 가득차 있을 경우 점수를 더해주고 그 행을 건너뛰면서 새로운 배열에 채워준다. 이렇게 한다면 마치 사라지는 효과를 볼 수 있다.

마지막으로 0,1 행을 확인해서 블록이 있는 행의 수만큼 건너뛰고 새로운 배열을 생성해서 채워주는 식으로 없애면 된다. 그렇게 된 후, 마지막으로 남아있는 블록 수 까지 세어준다면 정답을 도출할 수 있다.

이렇게 Python로 백준의 "모노미노도미노 2" 문제를 해결해보았습니다. 코드와 개념 설명을 참고하여 문제를 해결하는 데 도움이 되셨길 바랍니다! 😊

0개의 댓글