개념

완전 탐색은 답이 될 수 있는 후보를 모두 확인하여 문제를 해결하는 방법입니다. 각 후보가 조건을 만족하는지 검사하고, 문제에서 요구하는 결과를 구합니다.

조건을 만족하는 후보의 개수를 구할 때는 하나씩 세고, 가장 좋은 값을 구할 때는 지금까지 확인한 값과 비교해 갱신합니다. 예를 들어 여러 수의 쌍 중 합이 가장 큰 쌍을 찾는다면, 모든 쌍의 합을 계산하면서 가장 큰 값을 저장합니다.

후보의 범위 정하기

먼저 무엇을 하나의 후보로 볼지 정합니다. 두 칸에 각각 11부터 33까지의 수를 적는다면, 두 칸에 적힌 수의 쌍 하나가 후보입니다. 칸의 순서를 구분하므로 (1,2)(1,2)와 (2,1)(2,1)은 서로 다른 후보입니다.

첫 번째 수를 하나 정한 뒤 두 번째 수를 1,2,31,2,3으로 바꾸면 다음과 같이 모든 후보를 나열할 수 있습니다.

첫 번째 수확인할 후보
11(1,1),(1,2),(1,3)(1,1),(1,2),(1,3)
22(2,1),(2,2),(2,3)(2,1),(2,2),(2,3)
33(3,1),(3,2),(3,3)(3,1),(3,2),(3,3)

첫 번째 수가 11인 세 후보를 확인한 뒤 22인 세 후보, 33인 세 후보를 확인합니다. 첫 번째 수가 될 수 있는 값마다 두 번째 수가 될 수 있는 값을 모두 확인하므로, 가능한 아홉 쌍이 정확히 한 번씩 나옵니다.

조건을 검사하고 답 구하기

두 수의 합이 44인 경우의 수를 구한다면, 각 후보의 두 값을 더해 44와 같은지 확인합니다.

첫 번째 수각 후보의 합조건을 만족하는 후보
112,3,42,3,4(1,3)(1,3)
223,4,53,4,5(2,2)(2,2)
334,5,64,5,6(3,1)(3,1)

조건을 만족하는 후보를 하나씩 세면 답은 33입니다. 이처럼 후보를 나열하는 과정과 각 후보를 검사하는 과정을 정하면 완전 탐색을 구성할 수 있습니다.

탐색 비용

완전 탐색의 계산량은 후보 수와 후보 하나를 검사하는 비용으로 정해집니다. 두 수를 각각 11부터 NN까지 고르면 후보가 N2N^2개이고, 각 후보에서는 덧셈과 비교를 한 번씩 수행합니다.

N=100N=100이면 10 00010\,000쌍, N=100 000N=100\,000이면 100100억 쌍을 확인해야 합니다. 입력의 최댓값으로 후보 수를 계산하여 시간 제한 안에 모두 확인할 수 있는지 판단합니다.

복잡도

두 반복문으로 수의 쌍을 확인하는 경우입니다. 현재 두 수와 조건을 만족하는 개수만 저장하므로 추가 공간은 일정합니다.

연산시간복잡도공간복잡도
두 수의 모든 쌍 확인O(N2)O(N^2)추가 O(1)O(1)

예제

문제

두 칸에 각각 11부터 NN까지의 수를 적는다. 두 수의 합이 목표값과 같은 경우의 수를 구하여라. 두 칸의 순서는 구분한다.

입력

첫째 줄에 각 칸에 적을 수 있는 수의 최댓값 NN과 목표 합 SS가 공백을 사이에 두고 주어진다. 1≤N≤61\le N\le6; 2≤S≤122\le S\le12이다.

출력

조건을 만족하는 경우의 수를 출력한다.

예제 입력

3 4

예제 출력

3

예제 코드

C++20

#include <iostream>

using namespace std;

int main() {
    int n, s, i, j, cnt;

    cin >> n >> s;
    cnt = 0;

    for (i = 1; i <= n; ++i) {
        for (j = 1; j <= n; ++j) {
            if (i + j == s) ++cnt;
        }
    }

    cout << cnt << '\n';
}