JB의 이모저모

[BOJ 3019 🥈1] 테트리스 (Python) 본문

알고리즘/백준

[BOJ 3019 🥈1] 테트리스 (Python)

J B 2023. 9. 30. 15:34

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

 

3019번: 테트리스

테트리스는 C열 필드위에서 플레이하는 유명한 게임이다. 필드의 행의 수는 무한하다. 한 번 움직일 때, 아래와 같은 일곱가지 블록 중 하나를 필드에 떨어뜨릴 수 있다. 블록을 떨어뜨리기 전에

www.acmicpc.net

문제

테트리스는 C열 필드위에서 플레이하는 유명한 게임이다. 필드의 행의 수는 무한하다. 한 번 움직일 때, 아래와 같은 일곱가지 블록 중 하나를 필드에 떨어뜨릴 수 있다.

블록을 떨어뜨리기 전에, 플레이어는 블록을 90, 180, 270도 회전시키거나 좌우로 움직일 수 있다. 이때, 블록이 필드를 벗어나지 않으면 된다. 블록을 필드의 바닥이나 이미 채워져있는 칸의 위에 놓여지게 된다.

창영이가 하고있는 테트리스는 일반적인 테트리스와 약간 규칙이 다르다. 블록이 떨어졌을 때, 블록과 블록 또는 블록과 바닥 사이에 채워져있지 않은 칸이 생기면 안 된다.

예를 들어, 아래와 같이 각 칸의 높이가 2, 1, 1, 1, 0, 1인 경우를 생각해보자. 블록 5번을 떨어뜨리는 방법의 수는 아래와 같이 다섯가지이다.

테트리스 필드의 각 칸의 높이와 떨어뜨려야 하는 블록의 번호가 주어진다. 이때, 블록을 놓는 서로 다른 방법의 수를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 C와 떨어뜨리는 블록의 번호 P가 주어진다. (1 ≤ C ≤ 100, 1 ≤ P ≤ 7)

둘째 줄에는 각 칸의 높이가 주어진다. 높이는 0보다 크거나 같고, 100보다 작거나 같은 자연수이다.

출력

첫째 줄에 블록을 떨어뜨리는 방법의 수를 출력한다.

예제 입력 1 

6 5
2 1 1 1 0 1

예제 출력 1 

5

예제 입력 2 

5 1
0 0 0 0 0

예제 출력 2 

7

예제 입력 3 

9 4
4 3 5 4 6 5 7 6 6

예제 출력 3 

1

 

⭕ CODE

c, p = map(int, input().split())

arr = list(map(int, input().split()))

result = 0

# 길쭉한모양
if p == 1:
    # 세워서 모든 열에 다 가능하므로
    result += c
    # 연속한 4바닥 높이가 같다면 가능하므로
    for i in range(3, c):
        if arr[i - 3] == arr[i - 2] and arr[i - 3] == arr[i - 1] and arr[i - 3] == arr[i]:
            result += 1

# 네모모양
elif p == 2:
    # 연속한 2개 높이가 같다면
    for i in range(1, c):
        if arr[i - 1] == arr[i]:
            result += 1

elif p == 3:
    for i in range(2, c):
        # 왼쪽 2개의 높이가 같고 오른쪽 높이가 왼쪽 2개보다 한개 더 높다면 가능
        if arr[i - 2] == arr[i - 1] and arr[i - 1] == arr[i] - 1:
            result += 1
        # 왼쪽 높이가 오른쪽 높이보다 1 높다면
        if arr[i - 1] - 1 == arr[i]:
            result += 1
    # 맨 앞줄의 경우
    if arr[0] - 1 == arr[1]:
        result += 1

elif p == 4:
    for i in range(2, c):
        # 왼쪽 한개의 높이가 오른쪽 2개의 높이보다 1 크다면
        if arr[i - 2] - 1 == arr[i - 1] and arr[i - 1] == arr[i]:
            result += 1
        # 왼쪽의 높이보다 오른쪽의 높이가 1 크다면
        if arr[i - 1] == arr[i] - 1:
            result += 1
    # 맨 앞칸의 경우 
    if arr[0] == arr[1] - 1:
        result += 1

# ㅗ 모양
elif p == 5:
    
    for i in range(2, c):
        # 연속한 3개의 높이가 같다면 ( ㅗ 모양 )
        if arr[i - 2] == arr[i - 1] and arr[i - 2] == arr[i]:
            result += 1
        # 왼쪽의 높이가 중간의 높이보다 1 높다면 ( ㅓ 모양 )
        if arr[i - 2] - 1 == arr[i - 1]:
            result += 1
        # 오른쪽의 높이가 중간의 높이보다 1 높다면 ( ㅏ 모양 )
        if arr[i - 1] == arr[i] - 1:
            result += 1
        # 중간에 높이가 1 낮다면 ( ㅜ 모양 )
        if arr[i - 2] - 1 == arr[i - 1] and arr[i - 1] == arr[i] - 1:
            result += 1

elif p == 6:
    for i in range(1, c):
        # 두면이 연속한다면
        if arr[i - 1] == arr[i]:
            result += 1
        # index에러를 방지하기 위해 i는 2 이상
        # 연속한 3개의 높이가 같다면
        if i >= 2 and arr[i - 2] == arr[i - 1] and arr[i - 2] == arr[i]:
            result += 1
        # 왼쪽 한개의 높이가 오른쪽 2개의 높이보다 1 작다면
        if i >= 2 and arr[i - 2] == arr[i - 1] - 1 and arr[i - 1] == arr[i]:
            result += 1
        # 왼쪽 높이가 오른쪽 보다 2 높다면
        if arr[i - 1] - 2 == arr[i]:
            result += 1

elif p == 7:
    for i in range(1, c):
        # 두면이 연속한다면
        if arr[i - 1] == arr[i]:
            result += 1
        # index 에러를 방지하기 위해 i는 2 이상
        # 연속한 3개의 높이가 같다면
        if i >= 2 and arr[i - 2] == arr[i - 1] and arr[i - 2] == arr[i]:
            result += 1
        # 오른쪽 한개의 높이가 왼쪽 2개의 높이보다 1 작다면
        if i >= 2 and arr[i - 2] == arr[i - 1] and arr[i - 1] - 1 == arr[i]:
            result += 1
        # 오른쪽의 높이가 왼쪽보다 2 높다면
        if arr[i - 1] == arr[i] - 2:
            result += 1
print(result)

✏️ Comment

문제의 조건을 따라가며 풀었다. 단순 구현