[백준 알고리즘] 2422번: 한윤정이 이탈리아에 가서 아이스크림을 사먹는데

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

문제

문제

한윤정과 친구들은 이탈리아로 방학 여행을 갔다. 이탈리아는 덥다. 윤정이와 친구들은 아이스크림을 사먹기로 했다. 아이스크림 가게에는 N종류의 아이스크림이 있다. 모든 아이스크림은 1부터 N까지 번호가 매겨져있다. 어떤 종류의 아이스크림을 함께먹으면, 맛이 아주 형편없어진다. 따라서 윤정이는 이러한 경우를 피하면서 아이스크림을 3가지 선택하려고 한다. 이때, 선택하는 방법이 몇 가지인지 구하려고 한다.

입력

첫째 줄에 정수 N과 M이 주어진다. N은 아이스크림 종류의 수이고, M은 섞어먹으면 안 되는 조합의 개수이다. 아래 M개의 줄에는 섞어먹으면 안 되는 조합의 번호가 주어진다. 같은 조합은 두 번 이상 나오지 않는다. (1 ≤ N ≤ 200, 0 ≤ M ≤ 10,000)

출력

첫째 줄에, 가능한 방법이 총 몇 개 있는지 출력한다.

풀이

그냥 중첩루프로 풀면 되는 문제인데 백트래킹으로 해보려다가 시간초과가 계속 났다. 백트래킹으로 하는 것이 불가능한 이유는 순서에 상관없이 조합을 계속 만들기 때문에 순서만 다르고 중복되는 조합을 계속해서 생성하기 때문이다. 그래서 단순하게 중첩된 루프를 이용하고 미리 만들어둔 안되는 조합 맵핑을 이용해서 사용해도 되는 조합의 개수를 세어주면 된다.

코드

#include <iostream>
#include <vector>

using namespace std;

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(NULL);

    int cnt = 0;
    int N, M;

    cin >> N >> M;
    vector<vector<bool>> disallowComb(N + 1, vector<bool>(N + 1, false));

    for (int i = 0;i < M; i++) {
        int a, b;
        cin >> a >> b;
        disallowComb[a][b] = true;
        disallowComb[b][a] = true;
    }

    for (int i = 1; i <= N; i++) {
        for (int j = i + 1; j <= N; j++) {
            for (int k = j + 1; k <= N; k++) {
                if (!disallowComb[i][j] && !disallowComb[i][k] && !disallowComb[j][k]) {
                    cnt++;
                }
            }
        }
    }

    cout << cnt;
}

Written by@전여훈 (Click Me!)
고민이 담긴 코드를 만들자, 고민하기 위해 공부하자.