백준 15663번: N과 M(9)

백준알고리즘코딩 테스트Java
avatar
2025.06.14
·
3 min read

문제

N개의 자연수와 자연수 M이 주어졌을 때, 아래 조건을 만족하는 길이가 M인 수열을 모두 구하는 프로그램을 작성하시오.

  • N개의 자연수 중에서 M개를 고른 수열

입력

첫째 줄에 N과 M이 주어진다. (1 ≤ M ≤ N ≤ 8)

둘째 줄에 N개의 수가 주어진다. 입력으로 주어지는 수는 10,000보다 작거나 같은 자연수이다.

출력

한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다.

수열은 사전 순으로 증가하는 순서로 출력해야 한다.


나의 풀이

  • 입력 배열을 정렬하여 사전 순 출력을 유도

  • visited[] 배열을 사용하여 중복 선택 방지

  • Set<String>을 사용하여 동일 수열 중복 제거

  • 백트래킹(DFS)으로 모든 가능한 경우를 탐색

나의 코드

import java.io.*;
import java.util.*;

/**
 * 백준 15663 N 과 M (9) - 백 트래킹
 * <a href="https://www.acmicpc.net/problem/15663">...</a>
 */
public class Main {

    static int N, M;
    static int[] arr;
    static int[] tmp;
    static StringBuilder sb;
    static boolean[] visited;
    static Set<String> set;

    static void DFS(int depth) {
        if (depth == M) {
            StringBuilder temp = new StringBuilder();
            for (int i = 0; i < M; i++) {
                temp.append(tmp[i]).append(' ');
            }

            String t = temp.toString();
            if (!set.contains(t)) {
                set.add(t);
                sb.append(t).append("\n");
            }

            return;

        }

        for (int i = 0; i < N; i++) {
            if (!visited[i]) {
                visited[i] = true;
                tmp[depth] = arr[i];
                DFS(depth + 1);
                visited[i] = false;
            }
        }
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        sb = new StringBuilder();
        StringTokenizer st;

        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());

        arr = new int[N];
        tmp = new int[M];
        visited = new boolean[N];
        set = new HashSet<>();

        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < N; i++) {
            arr[i] = Integer.parseInt(st.nextToken());
        }

        Arrays.sort(arr);

        DFS(0);

        System.out.println(sb);
    }
}

시간복잡도

  • 백트래킹에서 각 깊이마다 최대 N개의 선택지를 탐색하므로 최악의 경우 O(N^M)







- 컬렉션 아티클