https://www.acmicpc.net/problem/15649
15649번: N과 M (1)
한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다. 수열은 사전 순으로 증가하는 순서로 출력해
www.acmicpc.net
백준 15649번 N과 M(1) 문제 링크입니다.
핵심
이 문제는 백트래킹을 사용하여서 풀어야 한다. 재귀 호출을 통해 푸는 방식이다.
https://namu.wiki/w/%EB%B0%B1%ED%8A%B8%EB%9E%98%ED%82%B9
백트래킹 - 나무위키
일반적으로 특정 퀘스트나 스토리를 클리어하기 위해 게임을 진행한 뒤, 자동으로 초기 지점으로 돌아오는 기능 등이 없어 왔던 길을 플레이어가 직접 캐릭터를 조정해 처음부터 다시 돌아와야
namu.wiki
정답 코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static int[] arr;
public static boolean[] check;
public static StringBuilder sb = new StringBuilder();
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
arr = new int[M];
check = new boolean[N];
rec(M,N,0);
System.out.println(sb);
}
public static void rec(int M, int N, int index) {
if(M==index) {
for(int val : arr) {
sb.append(val).append(' ');
}
sb.append('\n');
return;
}
for(int i=0; i <N;i++) {
if(!check[i]) {
check[i]=true;
arr[index]=i+1;
rec(M, N, index + 1);
check[i]=false;
}
}
}
}
해설
처음에는 숫자의 범위가 들어오고, 그 뒤 순열의 수를 받는다.
재귀 함수 rec 호출하는데, 처음 index값을 0으로 호출한다.
check는 이미 사용된 수인지 확인하기 위해 사용된다.
사용된 수가 아니라면, check를 사용했으므로 바꾸고, arr에 값을 추가한다.
이후 index값을 1 더한 자기 자신을 호출한다.
만약 M==index가 되면 배열을 sb에 추가시키고, 리턴된다.
이것은 순열의 크기가 원하는 크기와 동일하게 되었다는 의미이다.
리턴되면, check [i]는 사용되지 않음으로 바뀌게 된다.
그전 트리로 돌아간다.
이를 반복한다.
모든 과정이 끝났다면, sb에 추가된 배열의 순서를 출력한다.
개선점이나 오류가 있다면, 댓글 부탁드립니다.
'PS > 알고리즘 문제풀이' 카테고리의 다른 글
[백준]2004번 조합0의 개수(java) (0) | 2022.07.17 |
---|---|
[백준]15650번 N과M(2) (java) (0) | 2022.07.16 |
[백준]1002번 터렛(java) (0) | 2022.07.13 |
[백준]2477번 참외밭(java) (0) | 2022.07.13 |
[백준]7568번 덩치(java) (1) | 2022.07.12 |