https://www.acmicpc.net/problem/20061
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" 문제를 해결해보았습니다. 코드와 개념 설명을 참고하여 문제를 해결하는 데 도움이 되셨길 바랍니다! 😊