영원히 남는 기록, 재밌게 쓰자

백준 [15649] N과 M (1) 본문

Algorithm/백준

백준 [15649] N과 M (1)

youngjae-kim 2024. 2. 18. 15:18
728x90
반응형
 

15649번: N과 M (1)

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

www.acmicpc.net

 

 

풀이

  • 중복 없이 N개 중 M개를 골라야 한다.

조금 헷갈릴 수 있었던 부분이 [1, 2], [2, 1]은 중복되는 수열이라고 생각했었는데 순서가 달라서 다른 수열로 본다는 것을 나중에 이해했다..ㅋㅋ

 

한번 뽑은 수를 그 다음에 뽑지 않으면 중복을 없앨 수 있다.

방문 배열을 활용하여 한번 뽑은 수를 그 다음에 뽑지 않도록 체크를 해주어 중복 없이 M개를 뽑을 수 있다.

 

백트래킹 중 dfs를 사용하여 문제를 해결했다.

 

백트래킹 기법은 모든 경우의 수를 다 탐색하는 브루트 포스 방식과 다르게 유망성을 판단(조건을 주어)하여 조건에 걸리는 경우만 탐색하여 탬색 범위를 많이 줄이는 탐색 기법이다.

 

 

정답 코드

package com.baekjoon.p15649;

import java.util.*;

public class Main {
    static int n, m;
    static int[] arr, selected;
    static boolean[] visit;
    static StringBuilder sb = new StringBuilder();

    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);

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

        arr = new int[n]; // 뽑을 배열
        visit = new boolean[n];
        selected = new int[m];

        for (int i = 1; i <= n; i++) {
            arr[i - 1] = i;
        }

        pop(0);

        System.out.println(sb);
        sc.close();
    }

    private static void pop(int cnt) {
        if (cnt == m) {
            for (int i : selected) {
                sb.append(i + " ");
            }
            sb.append("\n");
            return;
        }

        for (int i = 0; i < n; i++) {
            if (!visit[i]) {
                visit[i] = true;
                selected[cnt] = i + 1;
                pop(cnt + 1);
                visit[i] = false;
            }
        }
    }
}

 

 

728x90
반응형

'Algorithm > 백준' 카테고리의 다른 글

백준 [13913] 숨바꼭질 4  (0) 2024.02.21
백준 [15651] N과 M (3)  (0) 2024.02.18
백준 [15650] N과 M (2)  (0) 2024.02.18
백준 [7576] 토마토 (JAVA)  (0) 2024.02.14
백준 [1697] 숨바꼭질  (0) 2024.02.07