coding test

[Java] 15649. N과 M (1)

잔망루피 2021. 8. 29. 14:31

문제

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

  • 1부터 N까지 자연수 중에서 중복 없이 M개를 고른 수열

입력

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

 

출력

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

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

 

예제 입력 1

3 1

예제 출력 1

1
2
3

 

예제 입력 2

4 2

 

예제 출력 2

1 2
1 3
1 4
2 1
2 3
2 4
3 1
3 2
3 4
4 1
4 2
4 3

 

예제 입력 3

4 4

예제 출력 3

1 2 3 4
1 2 4 3
1 3 2 4
1 3 4 2
1 4 2 3
1 4 3 2
2 1 3 4
2 1 4 3
2 3 1 4
2 3 4 1
2 4 1 3
2 4 3 1
3 1 2 4
3 1 4 2
3 2 1 4
3 2 4 1
3 4 1 2
3 4 2 1
4 1 2 3
4 1 3 2
4 2 1 3
4 2 3 1
4 3 1 2
4 3 2 1

 

 

💛 나의 풀이

import java.util.*;
class Main {
    public static void main(String[] args) {
        LinkedList<Integer> lst=new LinkedList<>();
        Scanner sc=new Scanner(System.in);
        String[] nm=sc.nextLine().split(" ");
        int n =Integer.parseInt(nm[0]);
        int m=Integer.parseInt(nm[1]);
        dfs(n, m, lst);
    }

    public static void dfs(int n, int m, LinkedList<Integer> lst){
        if(lst.size() == m){
            Iterator it=lst.iterator();
            while(it.hasNext()){
                System.out.print(it.next()+" ");
            }
            System.out.println();
            return;
        }
        for(int i=1; i<=n; i++){
            if(!lst.contains(i)) {
                lst.add(i);
                dfs(n, m, lst);
                lst.removeLast();
            }
        }
    }
}

백트래킹 풀이

파이썬 풀이 보고 자바로 구현해봤다.

출력할 때 iterator를 사용했다.

 

 

📌 다른 사람 풀이

 

# https://jiwon-coding.tistory.com/21
n, m=list(map(int, input().split()))
s=[]

def dfs() :
    if len(s) == m :
        print(' '.join(map(str, s)))    # 공백으로 구분
        return

    for i in range(1, n+1) :    # 1부터 n까지의 수
        if i not in s :
            s.append(i)
            dfs()
            s.pop()

dfs()

not in으로 중복된 수를 넣지 않으면서 s에 추가한다.

리스트 s가 길이 m이 되면 출력하고 return한다.

return 후에는 pop이 실행된다.

왔던 길을 다시 돌아가는 것이다.

 

 

// https://st-lab.tistory.com/114
import java.util.*;

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

    public static void main(String[] args) {
        Scanner in=new Scanner(System.in);

        int N=in.nextInt();
        int M=in.nextInt();

        arr=new int[M];
        visit=new boolean[N];
        dfs(N, M, 0);
        System.out.println(sb);
    }

    public static void dfs(int N, int M, int depth){
        if(depth == M){
            for(int val : arr){
                sb.append(val).append(' ');
            }
            sb.append('\n');
            return;
        }

        for(int i=0; i<N; i++){
            if(!visit[i]){
                visit[i]=true;
                arr[depth]=i+1;
                dfs(N, M, depth+1);
                visit[i]=false;
            }
        }
    }
}

StringBuilder에 다 담고 한 번에 출력하는 방식이 내 코드보다 효율이 좋다.

 

 

문제 출처 👉 백준

반응형

'coding test' 카테고리의 다른 글

[Java] 9095. 1, 2, 3 더하기  (0) 2021.08.30
[Java] 9663. N-Queen  (0) 2021.08.29
[파이썬, Java] [1차] 다트 게임  (0) 2021.08.27
[파이썬] [1차] 비밀지도  (0) 2021.08.27
[파이썬, Java] [1차] 캐시  (0) 2021.08.26