Python/BOG_14500

hii_·2022년 6월 8일
0

BOG

목록 보기
18/22

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

  • 문제
    폴리오미노란 크기가 1×1인 정사각형을 여러 개 이어서 붙인 도형이며, 다음과 같은 조건을 만족해야 한다.
    정사각형은 서로 겹치면 안 된다.
    도형은 모두 연결되어 있어야 한다.
    정사각형의 변끼리 연결되어 있어야 한다. 즉, 꼭짓점과 꼭짓점만 맞닿아 있으면 안 된다.
    정사각형 4개를 이어 붙인 폴리오미노는 테트로미노라고 하며, 다음과 같은 5가지가 있다.
    아름이는 크기가 N×M인 종이 위에 테트로미노 하나를 놓으려고 한다. 종이는 1×1 크기의 칸으로 나누어져 있으며, 각각의 칸에는 정수가 하나 쓰여 있다.
    테트로미노 하나를 적절히 놓아서 테트로미노가 놓인 칸에 쓰여 있는 수들의 합을 최대로 하는 프로그램을 작성하시오.
    테트로미노는 반드시 한 정사각형이 정확히 하나의 칸을 포함하도록 놓아야 하며, 회전이나 대칭을 시켜도 된다.

  • 입력
    첫째 줄에 종이의 세로 크기 N과 가로 크기 M이 주어진다. (4 ≤ N, M ≤ 500)
    둘째 줄부터 N개의 줄에 종이에 쓰여 있는 수가 주어진다. i번째 줄의 j번째 수는 위에서부터 i번째 칸, 왼쪽에서부터 j번째 칸에 쓰여 있는 수이다. 입력으로 주어지는 수는 1,000을 넘지 않는 자연수이다.

  • 출력
    첫째 줄에 테트로미노가 놓인 칸에 쓰인 수들의 합의 최댓값을 출력한다.

DFS는 진짜 오랜만에 풀어봤당
처음에 BFS문제인줄 알고 방향 잘못잡았다가 혼란스러웠음..
풀이들이 되게 다양했는데 내 아이디어와 가장 비슷한 풀이를 보고 참고하였다. 각 좌표마다 dfs로 4단계까지 탐색하고 값이 가장 큰 것을 찾는다는 것까지는 비슷했는데 내가 미처 생각하지 못했던 것은 ㅗ ㅜ ㅓ ㅏ 모양은 2단계에서 현위치에서 재탐색해야한다는 점이었다.

# 포인트 : 너무길면 함수로만들기, max_val로 계산해서 안될거같으면 재빨리 포기, dfs는 큐안쓰고 재귀
# 참고 : - map 사용법: https://koos808.tistory.com/34
def dfs(x, y, step, sum):
    global ans    # 함수 밖에서 선언된 전역변수의 접근위해
    if step == 4:
        ans = max(ans, sum)
        return
    if sum + max_val * (4-step) < ans:    # 후순에 큰게 나와도 최대보다 작으면
        return
    dx = [-1, 1, 0, 0]  # 방향벡터
    dy = [0, 0, -1, 1]
    for i in range(4):
        nx = x + dx[i]
        ny = y + dy[i]
        if 0<=nx<n and 0<=ny<m and visited[nx][ny] == 0:
            visited[nx][ny] = 1
            dfs(nx, ny, step+1, sum+lst[nx][ny])
            visited[nx][ny] = 0
            if step == 2:  # ㅓ, ㅏ, ㅗ, ㅜ 만들기위함
                visited[nx][ny] = 1
                dfs(x, y, step + 1, sum + lst[nx][ny])    # 탐색은 현위치에서 다시
                visited[nx][ny] = 0


if __name__ == "__main__":
    n, m = map(int, input().split())
    lst = [list(map(int, input().split())) for i in range(n)]
    visited = [[0 for i in range(m)] for j in range(n)]    # 방문체크
    max_val = max(map(max, lst))    # 최댓값
    ans = 0
    step = 1
    for i in range(n):
        for j in range(m):
            visited[i][j] = 1    # (i,j)가 첫블록이라서 이것도 방문처리해줘야
            dfs(i, j, 1, lst[i][j])
            visited[i][j] = 0
    print(ans)
profile
🐢👩‍💻⛄🤍💜

0개의 댓글