일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- 9095
- AIDEEPDIVE
- C++
- 백준1463
- 백준
- 혁펜하임강의
- 혁펜하임
- AI강의
- 1463
- tensorflow
- CUDA
- 패스트캠퍼스
- c++ 기초
- 1로만들기
- pytorch
- C++ 백준
- 반복문
- for문
- C++ 공백 입력
- 패스트캠퍼스혁펜하임
- 조건문
- C++ 함수
- 비교연산자
- 백준9095
- cuDNN
- 백준C++
- 백준1026
- 혁펜하임강의후기
- precision
- 혁펜하임AI
- Today
- Total
코딩하는 덕구 🐶
110. [삼성기출6] Python 백준 14500 번 테트로미노 자세한 설명 본문
안녕하세요 코딩하는 덕구입니다.
백준 14500 번 테트로미노 입니다.
14500번: 테트로미노
폴리오미노란 크기가 1×1인 정사각형을 여러 개 이어서 붙인 도형이며, 다음과 같은 조건을 만족해야 한다. 정사각형은 서로 겹치면 안 된다. 도형은 모두 연결되어 있어야 한다. 정사각형의 변
www.acmicpc.net
먼저 백준 14500 번 테트로미노 파이썬 정답 코드입니다. 설명은 아래에 있습니다.
N, M = map(int, input().split())
paper = []
dir_x = [-1, 1, 0, 0] #세로축 상, 하, 좌, 우
dir_y = [0, 0, -1, 1] #가로축
visited = [[False for _ in range(M)]for _ in range(N)]
for _ in range(N):
paper.append(list(map(int, input().split())))
max_val = max(map(max, paper))
def DFS(x, y, cnt, total):
global ans
if ans >= total + max_val*(3 - cnt):
return
if cnt == 3:
ans = max(ans, total)
return
for i in range(4):
nx = x + dir_x[i]
ny = y + dir_y[i]
if 0 <= nx < N and 0 <= ny < M and not visited[nx][ny]:
if cnt == 1:
visited[nx][ny] = True
DFS(x, y, cnt + 1, total + paper[nx][ny])
visited[nx][ny] = False
visited[nx][ny] = True
DFS(nx, ny, cnt + 1, total + paper[nx][ny])
visited[nx][ny] = False
ans = 0
for i in range(N):
for j in range(M):
visited[i][j] = True
DFS(i, j, 0, paper[i][j])
visited[i][j] = False
print(ans)
문제 요약

NxM 크기의 종이가 있고, 종이는 1x1 사이즈의 칸으로 나누어져 있으며, 각 칸마다 서로 다른 숫자가 있습니다.
도형 중 하나를 적절히 놓아서 도형이 놓인 칸에 쓰여 있는 수들의 합을 최대로 하는 프로그램을 작성합니다.
문제 접근
도형들을 구현하는게 핵심입니다.
한 붓그리기, 즉 모든 점들을 한번씩만 이동하여 그릴 수 있는 도형은 dfs 로 구현이 가능합니다.
그럼 분홍색 도형을 제외한 모든 도형은 dfs 로 구현하고,
분홍색 도형은 dfs가 0, 1, 2, 3 순으로 탐색할때
2번 iteration째에 1번의 좌표에서 dfs를 진행하면 구현할 수 있습니다.
이런식으로요!
if cnt == 1:
visited[nx][ny] = True
DFS(x, y, cnt + 1, total + paper[nx][ny])
visited[nx][ny] = False
visited[nx][ny] = True
DFS(nx, ny, cnt + 1, total + paper[nx][ny])
visited[nx][ny] = False
Python 코드 구현
종이의 세로 N, 가로 M , 종이 paper, 탐색을 위한 dir_x, dir_y, visited를 구현해 줍니다.
N, M = map(int, input().split())
paper = []
dir_x = [-1, 1, 0, 0] #세로축 상, 하, 좌, 우
dir_y = [0, 0, -1, 1] #가로축
visited = [[False for _ in range(M)]for _ in range(N)]
종이의 정보를 받아 종이의 각 좌표에 저장하고,
프로그램의 동작속도 효율을 의해 가장 큰 값을 찾아 저장합니다.
for _ in range(N):
paper.append(list(map(int, input().split())))
max_val = max(map(max, paper))
좌표를 입력받아
해당 좌표에 모든 도형을 가능한 모든 방향으로 놓아서 도형안의 값을 더하고,
그 중 가장 큰 값을 출력하는 함수인 dfs 를 구현해봅시다.
def DFS(x, y, cnt, total):
가장 도형안의 숫자 합 중 가장 큰 숫자를 저장한 변수인 ans를 전역변수로 설정하고
불 필요한 동작을 줄이기 위해
남은 탐색 동안 가능한 큰 수가 들어와도 현재의 최대값을 넘을 수 없으면
해당 탐색은 종료합니다.
global ans
if ans >= total + max_val*(3 - cnt):
return
한 도형을 모두 탐색했다면 해당 도형안의 모든 숫자들의 합과 지금까지 가장 큰 숫자를 비교해서 더 큰 숫자를
지금까지 가장 큰 숫자를 저장하는 변수인 ans 에 저장합니다.
if cnt == 3:
ans = max(ans, total)
return
4가지 방향으로 dfs 를 동작시키는데
탐색할 다음 좌표가 그래프 안에 있을때, 아직 노드를 방문하지 않았을 때 dfs를 동작시키고,
for i in range(4):
nx = x + dir_x[i]
ny = y + dir_y[i]
if 0 <= nx < N and 0 <= ny < M and not visited[nx][ny]:
cnt가 1이면 (도형의 4개 정사각형 중 3번째 탐색이라면) 2가지로 dfs를 동작시킵니다.
1.
O O O 이 위치에서 (굵은 원) 다음 dfs를 진행할 때 이전 좌표(nx, ny가 아닌 x, y)에서 진행하게 되면 방문한 곳은 방문하지 않으므로
1
O O O 1번이나 2번으로 이동하게 되고, ㅗ, ㅜ, ㅏ, ㅓ 모양을 구현할 수 있습니다.
2
if cnt == 1:
visited[nx][ny] = True
DFS(x, y, cnt + 1, total + paper[nx][ny])
visited[nx][ny] = False
2. dfs를 그냥 동작시키면 한붓그리기로 그릴 수 있는 모든 도형이 나오므로,
2가지의 dfs동작으로 모든 폴리오미노를 구현 가능합니다.
visited[nx][ny] = True
DFS(nx, ny, cnt + 1, total + paper[nx][ny])
visited[nx][ny] = False
함수 구현이 끝났습니다.
이제 모든 좌표에 대해 모든 도형을 대보면서
도형안의 숫자들의 합이 가장 큰 경우를 찾고
ans = 0
for i in range(N):
for j in range(M):
visited[i][j] = True
DFS(i, j, 0, paper[i][j])
visited[i][j] = False
출력하면 됩니다.
print(ans)
파이썬 백준 14500 번 테트로미노 최종 코드입니다.
N, M = map(int, input().split())
paper = []
dir_x = [-1, 1, 0, 0] #세로축 상, 하, 좌, 우
dir_y = [0, 0, -1, 1] #가로축
visited = [[False for _ in range(M)]for _ in range(N)]
for _ in range(N):
paper.append(list(map(int, input().split())))
max_val = max(map(max, paper))
def DFS(x, y, cnt, total):
global ans
if ans >= total + max_val*(3 - cnt):
return
if cnt == 3:
ans = max(ans, total)
return
for i in range(4):
nx = x + dir_x[i]
ny = y + dir_y[i]
if 0 <= nx < N and 0 <= ny < M and not visited[nx][ny]:
if cnt == 1:
visited[nx][ny] = True
DFS(x, y, cnt + 1, total + paper[nx][ny])
visited[nx][ny] = False
visited[nx][ny] = True
DFS(nx, ny, cnt + 1, total + paper[nx][ny])
visited[nx][ny] = False
ans = 0
for i in range(N):
for j in range(M):
visited[i][j] = True
DFS(i, j, 0, paper[i][j])
visited[i][j] = False
print(ans)
백준 14500 번 테트로미노 자세한 설명 및 Python 코드였습니다.
감사합니다.
'알고리즘 문제 풀이' 카테고리의 다른 글
112. [삼성기출8]Python 백준 14502 번 연구소 자세한 설명 (0) | 2023.03.30 |
---|---|
111. [삼성기출7]Python 백준 14501 번 퇴사 자세한 설명 (0) | 2023.03.24 |
109. [삼성기출5] Python 백준 14499 번 주사위 굴리기 자세한 설명 (0) | 2023.03.21 |
108. [삼성기출4] Python 백준 13458 번 시험 감독 자세한 설명 (0) | 2023.03.18 |
107. [삼성기출3] Python 백준 3190 번 뱀 자세한 설명 (0) | 2023.03.18 |