[Algorithm /백준] N과 M (12)

2023. 11. 22. 01:00Algorithm/JAVA

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

N개의 자연수 중에서 M개를 고른 수열
같은 수를 여러 번 골라도 된다.
고른 수열은 비내림차순이어야 한다.
길이가 K인 수열 A가 A1 ≤ A2 ≤ ... ≤ AK-1 ≤ AK를 만족하면, 비내림차순이라고 한다.


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

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

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

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


[문제 해결 - 백트래킹]

import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
public class Main {

    private static int[] arr;
    private static Set<Integer> set = new HashSet<>();
    private static int n;
    private static int m;

    public static void main(String[] args) throws IOException {

        Scanner sc = new Scanner(System.in);

        n = sc.nextInt();
        m = sc.nextInt();

        //중복을 제거하기 위해 set에 넣음
        for (int i = 0; i < n; i++) {
            set.add(sc.nextInt());
        }

        Integer[] sortedArr = set.toArray(new Integer[0]);
        Arrays.sort(sortedArr);

        arr = Arrays.stream(sortedArr).mapToInt(Integer::intValue).toArray();

        Main ma = new Main();

        ma.backTracking(0, 0, "");
    }

    public void backTracking(int startIndex, int depth, String str) {
        if (depth == m) {
            System.out.println(str);
            return;
        } else {
        	//중복을 제거했기 때문에 i의 최대 n이 아니라 arr.length를 기준으로 잡아야함
            for (int i = startIndex; i < arr.length; i++) {
                backTracking(i, depth + 1, str + arr[i] + " ");
            }
        }
    }
}