문제
자연수 N과 M이 주어졌을 때, 아래 조건을 만족하는 길이가 M인 수열을 모두 구하는 프로그램을 작성하시오.
- 1부터 N까지 자연수 중에서 중복 없이 M개를 고른 수열
- 고른 수열은 오름차순이어야 한다.
입력
첫째 줄에 자연수 N과 M이 주어진다. (1 ≤ M ≤ N ≤ 8)
출력
한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다.
수열은 사전 순으로 증가하는 순서로 출력해야 한다.
풀이
문제를 보면 백트래킹 문제인것을 알 수 있다.
시간복잡도를 계산하자면 N까지의 수를 M의 값만큼 반복해서 구해야 하기때문에 O(N^M) 이 된다.
예시를 들자면 1~4까지의 수로 3길이의 수열을 만든다고 생각하면 4x4x4가 된다.
이 문제의 최대 N과 M은 8이고 그러면 8^8승 약 1600만이 되므로 시간상에서는 문제가 없다.
문제 내용으로 넘어가서 dfs방식으로 해야하는데 방문체크를 해줘야한다.
이유는 중복되는 수열을 여러번 출력하면 안된다. 이말의 예시를 들자면
N = 4, M= 2일때
1 2 수열이 나오면 2 1 수열은 중복되므로 출력되면 안된다. 그러기 위해서
dfs 안에 반복문에서 i = 1부터가 아니라 i=num부터로 설정했다. 그렇게되면
1 2 나온이후에 2로 시작하는 dfs에서는 2 1로 갈 수 없다. 2 3부터 시작인거다.
이런 방법으로 아래 코드를 짰다.
예제 입력 예시
4 2
예제 출력 예시
1 2
1 3
1 4
2 3
2 4
3 4
소스코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
//15650번 N과 M(2)
public class Main {
static StringBuilder sb;
static int M;
static int N;
static boolean[] visited; //방문한 자연수 체크
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
M = Integer.parseInt(st.nextToken());
N = Integer.parseInt(st.nextToken());
visited = new boolean[M+1];
sb = new StringBuilder();
for (int i = 1; i <=M; i++) {
visited[i] = true;
dfs(i, N, "");
}
System.out.println(sb);
}
static void dfs(int num, int cnt, String str){
str = str+num+" ";
cnt--;
if(cnt != 0){
//기존 N과 M과다른점은 i=1부터가 아니라 i=num부터 해서 중복안됨 + 전에 나온 수열 중복x
for (int i = num; i <=M; i++) {
if(!visited[i]){
visited[i] = true; //dfs에 들어가기전 방문체크
dfs(i, cnt, str);
visited[i] = false; //dfs에 들어가고 난후 방문해제
}
}
}
else{
sb.append(str).append("\n");
}
}
}
문제 출처
https://www.acmicpc.net/problem/15650
'알고리즘 > 자바' 카테고리의 다른 글
[백준 알고리즘] 15652번 자바(Java) N과 M(4) (0) | 2023.08.04 |
---|---|
[백준 알고리즘] 9663번 자바(Java) N-Queen (0) | 2023.08.03 |
[백준 알고리즘] 1967번 자바(Java) 트리의 지름 (0) | 2023.07.26 |
[백준 알고리즘] 1697번 자바(Java) 숨바꼭질 BFS (2) | 2023.07.25 |
[백준 알고리즘] 2504번 자바(Java) 괄호의 값 (3) | 2023.07.21 |