완전탐색이란
완전탐색은 가능한 모든 경우의 수를 전부 체크해서 정답을 찾는 방법입니다.
무식하게 문제를 푼다는 의미로 "Brute Force" 라고도 부릅니다.
완전탐색은 시간복잡도가 주로 O(N^2) 이상이기 때문에, 입력의 개수(N)에 따른 시간 계산을 면밀히 해주어야 합니다.
완전탐색 알고리즘 유형
- Brute Force 기법 : 반복 / 조건문을 활용해 모두 테스트하는 방법
- 순열(Permutation) : n개 중 r개의 원소를 중복 허용 없이 나열하는 방법.
- 재귀(Recursive)
- 비트마스크(Bitmask) : 2진수 비트 연산을 통해 부분 집합을 표현하는 방법
- BFS, DFS : 그래프 자료구조에서 모든 정점을 탐색하기 위한 방법
예시문제
[Brute Force 기법 사용]
https://www.acmicpc.net/problem/2304
2304번: 창고 다각형
첫 줄에는 기둥의 개수를 나타내는 정수 N이 주어진다. N은 1 이상 1,000 이하이다. 그 다음 N 개의 줄에는 각 줄에 각 기둥의 왼쪽 면의 위치를 나타내는 정수 L과 높이를 나타내는 정수 H가 한 개의
www.acmicpc.net
코드 보기
import sys
input = sys.stdin.readline
N = int(input())
pl = [0 for _ in range(1001)] # 가능한 모든 x 좌표에 대해 기둥의 높이를 저장
maxH = 0
maxL = 0
for _ in range(N):
L, H = map(int, input().split())
if maxH < H:
maxL, maxH = L, H
pl[L] = H
# 모든 x 좌표를 돌며 조건에 따라 면적을 구해나간다 : 완전탐색!!
res = 0
curr = 0
# 왼쪽 그룹
for i in range(maxL+1):
curr = max(curr, pl[i])
res += curr
curr = 0
# 오른쪽 그룹
for i in range(1000, maxL, -1):
curr = max(curr, pl[i])
res += curr
print(res)
[Brute Force 기법 사용]
https://www.acmicpc.net/problem/2563
2563번: 색종이
가로, 세로의 크기가 각각 100인 정사각형 모양의 흰색 도화지가 있다. 이 도화지 위에 가로, 세로의 크기가 각각 10인 정사각형 모양의 검은색 색종이를 색종이의 변과 도화지의 변이 평행하도록
www.acmicpc.net
코드 보기
import sys
input = sys.stdin.readline
board = [[0 for _ in range(100)] for _ in range(100)]
size = 0
N = int(input())
arr = []
for _ in range(N):
x, y = map(int, input().split())
for i in range(x, x+10):
for j in range(y, y+10):
board[i][j] = 1
# 100*100개의 좌표를 모두 탐색하여 검은색 영역을 구함 : 완전탐색!!
for i in range(100):
for j in range(100):
size += board[i][j]
print(size)
[순열 사용]
https://www.acmicpc.net/problem/2503
2503번: 숫자 야구
첫째 줄에는 민혁이가 영수에게 몇 번이나 질문을 했는지를 나타내는 1 이상 100 이하의 자연수 N이 주어진다. 이어지는 N개의 줄에는 각 줄마다 민혁이가 질문한 세 자리 수와 영수가 답한 스트
www.acmicpc.net
코드 보기
import sys
import itertools
input = sys.stdin.readline
all_case = list(itertools.permutations([1,2,3,4,5,6,7,8,9], 3))
N = int(input())
for _ in range(N):
num, s, b = map(int, input().split())
num = list(str(num))
remove_cnt = 0
# 9P3의 모든 케이스와 num을 대조하여 Strike, Ball을 계산 : 완전탐색!!
for i in range(len(all_case)):
s_cnt = b_cnt = 0
i -= remove_cnt
for j in range(3):
num[j] = int(num[j])
if num[j] in all_case[i]:
if j == all_case[i].index(num[j]):
s_cnt += 1
else:
b_cnt += 1
if s != s_cnt or b != b_cnt:
all_case.remove(all_case[i])
remove_cnt += 1
print(len(all_case))
댓글