Coding Test/백준(Python)

[백준/Python] 14500번(구현)_테트로미노

syunze 2024. 2. 15. 17:03

📌문제 유형

구현, 브루트포스

 

📌문제

 

14500번: 테트로미노

폴리오미노란 크기가 1×1인 정사각형을 여러 개 이어서 붙인 도형이며, 다음과 같은 조건을 만족해야 한다. 정사각형은 서로 겹치면 안 된다. 도형은 모두 연결되어 있어야 한다. 정사각형의 변

www.acmicpc.net

 

 

📌나의 문제풀이

- 모든 경우의 수 다 동원해서 풀이

  • 각각의 블럭 모양 만들기 (단, S와 L은 좌우반전 고려해서 케이스 2개)
  • 종이의 판을 90도씩 3번 돌리기 -> 블럭 고정, 종이판을 돌리기

 * 주의 : S와 L은 좌우반전하면 y <= 0인 경우로 수정하기 (수정 안하면 85%)

# ㅡ 블럭
def long_block(x,y):
    total = 0
    if x < 0 or x >= len(maps) or y < 0 or len(maps[x]) <= y+3:
        return total

    for i in range(y,y+4):
        total += maps[x][i]
    return total

# 정사각형
def square_block(x,y):
    total = 0
    if 0 > y or len(maps[x]) <= y+1 or x < 0 or len(maps) <= x+1:
        return total

    total += maps[x][y]
    total += maps[x][y+1]
    total += maps[x+1][y]
    total += maps[x+1][y+1]
    return total

# L 블럭
def L_block(x,y):
    total = 0
    if y < 0 or len(maps[x])-1 < y+1 or x < 0 or len(maps)-1 < x+2:
        return total

    for i in range(x,x+3):
        total += maps[i][y]
    total += maps[x+2][y+1]
    return total

def L_block_2(x,y):
    total = 0
    if y <= 0 or len(maps[x])-1 < y or x < 0 or len(maps)-1 < x+2:
        return total

    for i in range(x,x+3):
        total += maps[i][y]
    total += maps[x+2][y-1]
    return total

# S 블럭
def S_block(x,y):
    total = 0
    if y < 0 or len(maps[x]) < y+2 or x < 0 or len(maps) < x+3:
        return total

    for i in range(x,x+2):
        total += maps[i][y]
    for j in range(x+1, x+3):
        total += maps[j][y+1]
    return total

def S_block_2(x,y):
    total = 0
    if y <= 0 or len(maps[x]) < y+1 or x < 0 or len(maps) < x+3:
        return total

    for i in range(x,x+2):
        total += maps[i][y]
    for j in range(x+1, x+3):
        total += maps[j][y-1]
    return total

# T 블럭
def T_block(x,y):
    total = 0
    if y < 0 or len(maps[x]) < y+3 or x < 0 or len(maps) < x+2:
        return total

    for i in range(y,y+3):
        total += maps[x][i]
    total += maps[x+1][y+1]
    return total

# 90도 회전
def rotate(arr):
    list_tuples = zip(*arr[::-1])
    return [list(l) for l in list_tuples]

n,m = map(int,input().split())

maps = []
for _ in range(n):
    rows = list(map(int,input().split()))
    maps.append(rows)

# 각 블럭별로 코드 짜고, maps를 90 도씩 옮겨서 계산하기
# return 값이 0 나오면 break로 멈추기 -> x를 다음 줄로 넘기기
ans = 0
for _ in range(4):
    for x in range(len(maps)):
        for y in range(len(maps[0])):
            a = long_block(x,y)
            b = square_block(x,y)
            c = L_block(x,y)
            d = S_block(x,y)
            e = T_block(x,y)
            f = L_block_2(x,y)
            g = S_block_2(x,y)

            result = max(a,b,c,d,e,f,g)
            if ans < result:
                ans = result
    maps = rotate(maps)
print(ans)

 

 

📌다른사람의 문제풀이

- DFS 이용 (단, ㅜ모양은 직접 만들기)

import sys
input = sys.stdin.readline

# 상, 하, 좌, 우
move = [(0, 1), (0, -1), (1, 0), (-1, 0)]

# INPUT
N, M = map(int, input().split())
board = [list(map(int,input().split())) for _ in range(N)]
visited = [[False] * M for _ in range(N)]

# 최대값 변수
maxValue = 0

# ㅗ, ㅜ, ㅓ, ㅏ 제외한 모양들 최대값 계산
def dfs(i, j, dsum, cnt):
    global maxValue
    # 모양 완성되었을 때 최대값 계산
    if cnt == 4:
        maxValue = max(maxValue, dsum)
        return

    # 상, 하, 좌, 우로 이동
    for n in range(4):
        ni = i+move[n][0]
        nj = j+move[n][1]
        if 0 <= ni < N and 0 <= nj < M and not visited[ni][nj]:
            # 방문 표시 및 제거
            visited[ni][nj] = True
            dfs(ni, nj, dsum + board[ni][nj], cnt+1)
            visited[ni][nj] = False


# ㅗ, ㅜ, ㅓ, ㅏ 모양의 최대값 계산
def exce(i, j):
    global maxValue
    for n in range(4):
        # 초기값은 시작지점의 값으로 지정
        tmp = board[i][j]
        for k in range(3):
            # move 배열의 요소를 3개씩 사용할 수 있도록 인덱스 계산
            # 012, 123, 230, 301
            t = (n+k)%4
            ni = i+move[t][0]
            nj = j+move[t][1]

            if not (0 <= ni < N and 0 <= nj < M):
                tmp = 0
                break
            tmp += board[ni][nj]
        # 최대값 계산
        maxValue = max(maxValue, tmp)


for i in range(N):
    for j in range(M):
        # 시작점 visited 표시
        visited[i][j] = True
        dfs(i, j, board[i][j], 1)
        visited[i][j] = False

        exce(i, j)

print(maxValue)

 

📌리뷰

- 테트로미노 모든 경우의 수 가능한지 확인

 

글 읽기 - << 테케 공유 >>

댓글을 작성하려면 로그인해야 합니다.

www.acmicpc.net

- 올 구현인 경우 범위 체크가 가장 중요 

728x90