chldkato

백준 19235 모노미노도미노 (파이썬) 본문

백준

백준 19235 모노미노도미노 (파이썬)

chldkato 2020. 6. 11. 22:18

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

 

19235번: 모노미노도미노

모노미노도미노는 아래와 같이 생긴 보드에서 진행되는 게임이다. 보드는 빨간색 보드, 파란색 보드, 초록색 보드가 그림과 같이 붙어있는 형태이다. 게임에서 사용하는 좌표 (x, y)에서 x는 행,

www.acmicpc.net

1. 파란색보드, 초록색보드 b와 g를 만든다. 각각 4x6, 6x4 크기의 행렬이다

2. 입력에 맞춰서 각각의 보드에 블록을 위치시킨다. (구현 방식은 똑같기 때문에 아래부터는 파란색보드만 설명)

3. 블록을 이동시킬 수 있는 만큼 이동한다. 2x1은 다음 두칸씩 고려해야한다

   여기서 x와 y 좌표는 나중에 0, 1번째 열에 블록이 있는지 확인할 때 쓰인다

4. 블록이 이동했으면 remove_blue를 실행해서 지울 수 있는 열을 지운다.

   remove_blue는 해당 열에 -1이 있으면 다음 열로 넘어가고 전부 채워져있으면 다시 -1로 리셋한 후 ans에 1을 더한다

5. 지운 열이 있으면 다시 전체 블록을 이동할 수 있는 만큼 이동한다

   단, 2x1 블록의 경우 두 블록이 분리되지않고 같이 떨어져야하기 때문에 따로 구현해야 한다

6. b[i][j] 와 b[i+1][j]가 같으면 붙어있는 두칸짜리 블록이므로 같이 이동하도록 구현한다

   위의 경우가 아니면 한칸짜리 블록이므로 이동할 수 있는만큼 이동하게 한다

7. 이동이 없거나(flag=0) 이동은 있으나 더 지울 블록이 없으면 break 한다. 지울블록이 없을때까지 과정을 반복한다

8. 0, 1번째 열에 블록이 있는지 확인한다. 블록이 있으면 조건대로 2칸 혹은 1칸 오른쪽으로 전체를 이동시킨다

   이동시킨 다음에는 0, 1번째 열에 있던 블록을 -1로 리셋한다

9. 초록색보드도 위와 같은 과정을 거치고 문제의 답을 출력한다

import sys
from copy import deepcopy

input = sys.stdin.readline

def remove_blue():
    global ans
    flag1 = 0
    for j in range(2, 6):
        flag2 = 0
        for i in range(4):
            if b[i][j] == -1:
                flag2 = 1
                break
        if flag2 == 1:
            continue
        flag1 = 1
        for i in range(4):
            b[i][j] = -1
        ans += 1
    return 1 if flag1 else 0


def remove_green():
    global ans
    flag1 = 0
    for i in range(2, 6):
        flag2 = 0
        for j in range(4):
            if g[i][j] == -1:
                flag2 = 1
                break
        if flag2 == 1:
            continue
        flag1 = 1
        for j in range(4):
            g[i][j] = -1
        ans += 1
    return 1 if flag1 else 0


def move_blue(t, x, num):
    y = 1
    if t == 1 or t == 2:
        while True:
            if y + 1 > 5 or b[x][y+1] != -1:
                b[x][y] = num
                if t == 2:
                    b[x][y-1] = num
                break
            y += 1

    else:
        while True:
            if y + 1 > 5 or b[x][y+1] != -1 or b[x+1][y+1] != -1:
                b[x][y], b[x+1][y] = num, num
                break
            y += 1

    if remove_blue():
        while True:
            flag = 0
            for j in range(4, 0, -1):
                for i in range(4):
                    if b[i][j] != -1 and b[i][j+1] == -1:
                        if i > 0 and b[i][j] == b[i-1][j]:
                            continue
                        if i < 3 and b[i][j] == b[i+1][j]:
                            d = 1
                            while True:
                                if j + d > 5:
                                    d -= 1
                                    break
                                if b[i][j+d] == -1 and b[i+1][j+d] == -1:
                                    d += 1
                                else:
                                    d -= 1
                                    break
                            if d:
                                b[i][j+d], b[i+1][j+d] = b[i][j], b[i][j]
                                b[i][j], b[i+1][j] = -1, -1
                                flag = 1
                            continue
                        d = 1
                        while True:
                            if j + d > 5:
                                d -= 1
                                break
                            elif b[i][j+d] == -1:
                                d += 1
                            else:
                                d -= 1
                                break
                        b[i][j+d] = b[i][j]
                        b[i][j] = -1
                        flag = 1

            if flag != 0 and not remove_blue():
                break
            if flag == 0:
                break

    if (y == 1 and b[x][y] != -1) or (y == 2 and b[x][y-1] != -1):
        for i in range(4):
            if t == 2 and y == 1:
                b[i][2:] = deepcopy(b[i][:4])
            else:
                b[i][2:] = deepcopy(b[i][1:5])

        if y == 2:
            y -= 1
        if t == 1:
            b[x][y] = -1
        elif t == 2:
            b[x][y], b[x][y-1] = -1, -1
        else:
            b[x][y], b[x+1][y] = -1, -1


def move_green(t, y, num):
    global ans
    x = 1
    if t == 1 or t == 3:
        while True:
            if x + 1 > 5 or g[x+1][y] != -1:
                g[x][y] = num
                if t == 3:
                    g[x-1][y] = num
                break
            x += 1

    else:
        while True:
            if x + 1 > 5 or g[x+1][y] != -1 or g[x+1][y+1] != -1:
                g[x][y], g[x][y+1] = num, num
                break
            x += 1

    if remove_green():
        while True:
            flag = 0
            for i in range(4, 0, -1):
                for j in range(4):
                    if g[i][j] != -1 and g[i+1][j] == -1:
                        if j > 0 and g[i][j] == g[i][j-1]:
                            continue
                        if j < 3 and g[i][j] == g[i][j+1]:
                            d = 1
                            while True:
                                if i + d > 5:
                                    d -= 1
                                    break
                                if g[i+d][j] == -1 and g[i+d][j+1] == -1:
                                    d += 1
                                else:
                                    d -= 1
                                    break
                            if d:
                                g[i+d][j], g[i+d][j+1] = g[i][j], g[i][j]
                                g[i][j], g[i][j+1] = -1, -1
                                flag = 1
                            continue
                        d = 1
                        while True:
                            if i + d > 5:
                                d -= 1
                                break
                            if g[i+d][j] == -1:
                                d += 1
                            else:
                                d -= 1
                                break
                        g[i+d][j] = g[i][j]
                        g[i][j] = -1
                        flag = 1

            if flag != 0 and not remove_green():
                break
            if flag == 0:
                break

    if (x == 1 and g[x][y] != -1) or (x == 2 and g[x-1][y] != -1):
        if t == 3 and x == 1:
            g[2:] = deepcopy(g[:4])
        else:
            g[2:] = deepcopy(g[1:5])

        if x == 2:
            x -= 1
        if t == 1:
            g[x][y] = -1
        elif t == 2:
            g[x][y], g[x][y+1] = -1, -1
        else:
            g[x][y], g[x-1][y] = -1, -1


tc = int(input())
b = [[-1 for _ in range(6)] for _ in range(4)]
g = [[-1 for _ in range(4)] for _ in range(6)]

ans = 0
for i in range(tc):
    t, x, y = map(int, input().split())
    move_blue(t, x, i)
    move_green(t, y, i)

cnt_b, cnt_g = 0, 0
for i in range(4):
    for j in range(2, 6):
        if b[i][j] != -1:
            cnt_b += 1
for i in range(2, 6):
    for j in range(4):
        if g[i][j] != -1:
            cnt_g += 1
print(ans)
print(cnt_b + cnt_g)

Comments