일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 쉬운코드
- SDK
- 인터럽트
- 프로세스 주소 공간
- 온디바이스AI
- recoverability
- 코딩애플
- 시그널 핸들러
- 백엔드
- 쉬운 코드
- B tree 데이터삽입
- 개발남노씨
- 커널 동기화
- 데이터베이스
- 코딩테스트 [ ALL IN ONE ]
- 네트워크
- 트랜잭션
- concurrency control
- 김영한
- CPU 스케줄링
- BreadcrumbsComputer-Networking_A-Top-Down-Approach
- 운영체제와 정보기술의 원리
- Git
- SQL
- 갤럭시 S24
- 시스템프로그래밍
- vite
- 운영체제
- Extendable hashing
- 반효경
- Today
- Total
티끌모아 태산
14500: 테트로미노 본문
https://www.acmicpc.net/problem/14500
14500번: 테트로미노
폴리오미노란 크기가 1×1인 정사각형을 여러 개 이어서 붙인 도형이며, 다음과 같은 조건을 만족해야 한다. 정사각형은 서로 겹치면 안 된다. 도형은 모두 연결되어 있어야 한다. 정사각형의 변
www.acmicpc.net
설명
맵 위에 테트로미노 하나를 놓아서 놓인 칸에 쓰여 있는 수들의 합을 최대로 구하는 문제이다. 테트로미노는 반드시 한 정사각형이 정확히 하나의 칸을 포함하도록 놓아야하며, 회전이나 대칭을 시켜도 된다.
핵심 아이디어
- DFS를 활용하기!
테트로미노를 살펴보면 5개중 4개는 DFS로 구현이 가능한데 한 개는 불가능하다. T자를 구현하기 위해서는 DFS를 돌 때, 현재 위치를 가리키는 커서를 움직이지 않도록 해야한다.
ㅜ 를 제외하고 나머지 테트로미노는 dfs로 상하좌우 최대 4번까지 돌려서 모양을 얻을 수 있지만 ㅜ는 특이 케이스로 따로 해주어야 한다.
이 모양들은 상 하 좌 우로 단 4번의 움직임으로 나올 수 있는 모양들이다. 이제 ㅜ 를 확인해 보자! 이 경우엔 가운데를 중심으로 3개의 사각형을 고려하면 된다. 즉 커서를 고정시킨다. 그래서 dfs로는 구현이 불가능하고 다음 4가지 경우를 순차적으로 확인하면 된다.
- dfs를 돌릴 때, 중복 방문을 피하기 위해 visited 2차원 배열을 만들어서 확인한다. dfs 탐색이 끝나면 다음 탐색을 위해서 방문 해제를 해준다.
visited = [[False] * m for _ in range(n)]
- ㅜ 모양의 주변 블럭 부분을 확인할 때 방향 한 개만 뺀 경우를 고려할 때는 좌표를 미리 적어두어 사용해도 된다. 여기서는 4방향 모두 탐색한 후 그 4방향의 수 중에서 가장 작은 수를 제거하고 모두 더하기!
length = len(arr)
if length == 4:
arr.sort(reverse=True) # 내림차순 정렬
arr.pop() # 가장 오른쪽 데이터 추출 후 삭제
max_value = max(max_value, sum(arr)+graph[x][y])
elif length == 3: # 3방향이면 바로 계산
max_value = max(max_value, sum(arr)+graph[x][y])
return # 2이하면 ㅗ 모양을 만들 수 없기 때문에 return
코드 구현
import sys
input = sys.stdin.readline
# 맵의 크기 입력받기
n, m = map(int, input().split())
graph = []
for _ in range(n):
graph.append(list(map(int, input().split())))
# 테트로미노를 놓았던 자리인지 확인하기 위한 배열
visited = [[False] * m for _ in range(n)]
# 상 하 좌 우
dx = [-1,1,0,0]
dy = [0,0,-1,1]
# 최댓값 변수
max_value = 0
# ㅗ,ㅜ,ㅓ,ㅏ를 제외한 모양들 dfs를 돌며 최댓값 구하기
def dfs(x,y, temp, count):
global max_value
# 모양이 완성되었을 때 최댓값 구하기
if count == 4:
max_value = max(max_value, temp)
return
else:
# 상 하 좌 우로 이동
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] == False:
visited[nx][ny] = True
dfs(nx,ny,temp+graph[nx][ny],count+1)
# 탐색 종료 후 다음 탐색을 위해 방문 해제
visited[nx][ny] = False
# ㅜ,ㅗ,ㅓ,ㅏ 모양의 최댓값 계산
def excep(x,y):
global max_value
# 초기값은 시작점으로 설정
temp = graph[x][y]
# 4방향 탐색 값을 저장할 배열
arr = []
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] == False:
arr.append(graph[nx][ny])
length = len(arr)
if length == 4:
arr.sort(reverse=True)
arr.pop() # 가장 오른쪽 데이터 추출 후 삭제!
max_value = max(max_value, sum(arr) + graph[x][y])
elif length == 3: # 3 방향만 들어가기 때문에 바로 sum
max_value = max(max_value, sum(arr) + graph[x][y])
return # length가 2 이하라면 ㅗ 모양이 아니므로 바로 return
# 이제 정답 출력하기
for i in range(n):
for j in range(m):
# 현재 위치는 방문처리
visited[i][j] = True
# dfs 탐색하기
dfs(i,j,graph[i][j], 1)
excep(i,j)
# 다음 탐색을 위해 방문처리 해제
visited[i][j] = False
print(max_value)
참고 블로그
https://cijbest.tistory.com/87
[백준 14500 : PYTHON] 테트로미노
문제 풀기 : 14500번 14500번: 테트로미노 폴리오미노란 크기가 1×1인 정사각형을 여러 개 이어서 붙인 도형이며, 다음과 같은 조건을 만족해야 한다. 정사각형은 서로 겹치면 안 된다. 도형은 모두
cijbest.tistory.com
https://cobokjang.tistory.com/9
[백준] 14500번(python 파이썬) - 테트로미노
문제 링크: https://www.acmicpc.net/problem/14500 14500번: 테트로미노 폴리오미노란 크기가 1×1인 정사각형을 여러 개 이어서 붙인 도형이며, 다음과 같은 조건을 만족해야 한다. 정사각형은 서로 겹치면
cobokjang.tistory.com
'백준 문제 > 삼성 기출' 카테고리의 다른 글
14891: 톱니바퀴 (0) | 2024.03.07 |
---|---|
21608: 상어 초등학교 (0) | 2024.03.05 |
19236: 청소년 상어 (1) | 2024.03.04 |