개발/algorithm

[백준 20061번] 모노미노도미노 - python

zzi_on2 2022. 10. 3. 17:31

문제 링크

문제 풀이 

1. move_blue, move_green : 블록 옮기기 

blue는 x 좌표 고정, y 좌표 늘리기 

green은 y 좌표 고정, x 좌표 늘리기 

2. check_blue, check_green : 제거 될 수 있는 블록 체크하기 

행이나 열 모두 채워졌는지 확인하고 제거할 수 있으면 remove 함수 열(행) 번호와 함께 실행 

0, 1 행이나 0,1 열에 있으면 remove 함수 5열(행) 번호와 함께 실행 

remove 함수 실행할 때마다 ans +1 

3. remove_blue, remove_green : 블록 제거하기

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

def check_blue():
    global ans 
        
    # 제거할 수 있는 블록 확인 
    for j in range(2,6):
        cnt = 0 
        for i in range(4):
            if blue[i][j]:
                cnt += 1 
            
        # 제거할 수 있으면 
        if cnt == 4 :
            remove_blue(j)
            ans += 1 

def remove_blue(col):
    # 블록 제거 
    for j in range(col, 0, -1):
        for i in range(4):
            blue[i][j] = blue[i][j-1]
    
    for i in range(4):
        blue[i][0] = 0 
        
def move_blue(t, x):
    y = 1 
    
    # 블록 이동 
    if t == 1 or t == 2 :
        while True :
            # 범위를 벗어나거나, 다른 블록이 있는 경우
            if y + 1 > 5 or blue[x][y+1] :
                blue[x][y] = 1 
                if t == 2 :
                    blue[x][y-1] = 1 
                break 
            y += 1 
            
    else :
        while True :
            # 범위를 벗어나거나, 다른 블록이 있는 경우 
            if y + 1 > 5 or blue[x][y+1] or blue[x+1][y+1]:
                blue[x][y] = 1 
                blue[x+1][y] = 1 
                break
            y += 1 
    
    # 제거할 수 있는 블록이 있는지 확인 
    check_blue()
    
    # 0,1 열에 블록이 있으면 제거 
    for j in range(2):
        for i in range(4):
            if blue[i][j]:
                remove_blue(5)
                break 
    
def check_green():
    global ans 
    
    # 제거할 수 있는 블록이 있는지 확인 
    for i in range(2,6):
        cnt = 0 
        for j in range(4): 
            if green[i][j] :
                cnt += 1
                
        if cnt == 4 :
            remove_green(i)
            ans += 1 
    
    
def remove_green(row):
    # 블록 제거 
    for i in range(row, 0, -1):
        for j in range(4):
            green[i][j] = green[i-1][j]       
        
    for j in range(4):
        green[0][j] = 0 
        
def move_green(t, y):
    
    x = 1 
    
    if t == 1 or t == 3 :
        while True :
            # 범위를 벗어나거나, 다른 블록이 있는 경우 
            if x + 1 > 5 or green[x+1][y]:
                green[x][y] = 1 
                if t == 3 :
                    green[x-1][y] = 1 
                break
            x += 1 
            
    if t == 2 :
        while True :
            # 범위를 벗어나거나, 다른 블록이 있는 경우 
            if x + 1 > 5 or green[x+1][y] or green[x+1][y+1]:
                green[x][y] = 1 
                green[x][y+1] = 1 
                break 
            x += 1 
            
    # 제거할 수 있는 블록이 있는지 확인 
    check_green()
    
    # 0, 1 행에 블록이 있으면 제거 
    for i in range(2):
        for j in range(4):
            if green[i][j] :
                remove_green(5)
                break
        
n = int(input())

blue = [ [0] * 6 for _ in range(4)]
green = [[0] * 4 for _ in range(6)]

ans = 0 
for _ in range(n):
    t, x, y = map(int,input().split())
    
    move_blue(t,x)
    move_green(t,y)
    
result = 0
 
# 파란 보드에 채워져 있는 블록 개수 세기 
for i in range(4):
    for j in range(2,6):
        if blue[i][j]:
            result += 1 
    
# 초록 보드에 채워져 있는 블록 개수 세기         
for i in range(2,6):
    for j in range(4):
        if green[i][j]:
            result += 1
            
print(ans)
print(result)