๋ฐฑํธ๋ํน ์ด๋?
๋ฐฑํธ๋ํน์ ๋ชจ๋ ์กฐํฉ์ ์๋ฅผ ์ดํด๋ณด์ง๋ง, ์กฐ๊ฑด์ด ๋ง์กฑํ ๋๋ง ์ดํด๋ณด๊ธฐ ๋๋ฌธ์
์ด๋ค ๊ฒฝ์ฐ์ ๋ฐ๋ผ ํจ์ฌ ๋น ๋ฅผ์๋ ์๋ค.
๋ฐฑํธ๋ํน ์คํ ์์
๋ฐฑํธ๋ํน์ DFS(๊น์ด ์ฐ์ ํ์)์ ๋จผ์ ์คํํ๋ฉด์ ๋ ์ด์ ํ์์ ์งํํ ์ ์๋ ์ํฉ์ด๋ฉด ๋ค์ ๋๋์ ๊ฐ์(๋ฐฑํธ๋ํน) ํ์์ ์งํํ๋ค.
๊ด๋ จ ๋ฌธ์ ๋ฅผ ํ์ด๋ณด๋ฉด ์ดํด๊ฐ ์ ๋ ๊ฒ์ด๋ค.
N๊ณผ M (1) ํ์ด๋ณด๊ธฐ
์์ฐ์ N์ด ์ฃผ์ด์ง๋ฉด 1๋ถํฐ N๊น์ง ์์ฐ์ ์ค์์ ์ค๋ณต ์์ด M๊ฐ๋ฅผ ๊ณ ๋ฅธ ์์ด์ ์ถ๋ ฅํ๋ฉด ๋๋ค.
์๋ฅผ ๋ค์ด,
N : 3 , M : 3 ์ผ๋, ์ค๋ณต ์์ด ์๋ ์ฒ๋ผ ์ถ๋ ฅ์ํค๋ฉด ๋๋ค.
------------------------------------------------
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
์ผ๋จ for๋ฌธ์ ๋๋ฉด์
for(int i=1; i<=N; i++) {
arr[index] = i; // i๋ฅผ ๋ฐฐ์ด์ ๋ฃ๋๋ค.
visited[i] = true; // i๋ฅผ ๋ฐฉ๋ฌธํ๋ค๊ณ ์ฒดํฌ
recursion(index + 1); // ๋ค์ ์ธ๋ฑ์ค ์์๋ฅผ ๋ฃ๊ธฐ ์ํด (index+1)์ฌ๊ท ํธ์ถ์ ํ๋ค.
visited[i] = false; // ์์ recursion์ด ๋๋ฌ์ผ๋ฏ๋ก, ๋ค์ i๋ก ๋์ด๊ฐ๊ธฐ ์ ์ ํ์ฌ i์ ๋ฐฉ๋ฌธ์ฌ๋ถ๋ฅผ false๋ก ๋ฐ๊ฟ์ค๋ค.
}
- 1-1) i = 1 ์ผ ๋
1์ ๋ฐฉ๋ฌธํ๋ค๊ณ ํ์ํ ๋ค, ๋ค์ 1์ ๋ฐฉ๋ฌธํ ๋ -> ์ด๋ฏธ ๋ฐฉ๋ฌธ ํ์ผ๋ฏ๋ก ๊ฑด๋ ๋ฐ๊ฒ ๋๋ค. (ํด๋น i์ visited ๊ฐ ํ์ธ)
// visited [O,X,X]
for(int i=1; i<=N; i++) {
if(!visited[i]) {
// ๋ฐฉ๋ฌธ ์ฌ๋ถ ํ์ธ! (์ํ์ ๊ฒฝ์ฐ์๋ง ์คํ)
visited[i] = true; // ๋ฐฉ๋ฌธ ์ํ์ผ๋ฉด ํด๋น i์ visited ๊ฐ์ true๋ก ๋ณ๊ฒฝ!
}
}
- 1-2) ํ์ฌ i๋ 2์ด๋ค.
๊ทธ๋ค์ 2๋ฅผ ๋ฐฉ๋ฌธํ ๋๋ visited[2] = false ์ด๋ฏ๋ก ๋ฐฉ๋ฌธ ํ๋ค.
๋ for๋ฌธ์ผ๋ก 1,2,3์ ์ฌ ๋ฐฉ๋ฌธ์ ํ๊ธฐ์ ์, i = 1, 2 -> ์ด๋ฏธ ๋ฐฉ๋ฌธ ํ๊ธฐ ๋๋ฌธ์ ๊ฑด๋ ๋ฐ๊ฒ ๋๊ณ , 3 ์ visited[3] = false ์ด๊ธฐ ๋๋ฌธ์, ๋ฐฉ๋ฌธํ ์ ์๋ค.
//visited [O,O,X]
for(int i=1; i<=N; i++) {
if(!visited[i]){
// i=3์ผ ๊ฒฝ์ฐ์๋ง ํด๋น!
visited[3] = true;
arr[index] = 3;
recursion(index + 1);
}
}
์ฌ๊ท ํธ์ถ์ ํ ๋ ๋๊ฒจ์ฃผ๋ index๊ฐ์ด M๊ณผ ๊ฐ์ ์ง๋ ์์ ์ ์ถ๋ ฅ์ ํ๋๋ก ํ๋ค.
// visited [O,O,O]
// arr [1,2,3]
// index = 3 , M = 3
if(index == M){ // ๋๊ฒจ ๋ฐ์ index๊ฐ M๊ณผ ๊ฐ์์ง๋ ์์ ์ ์คํ
for(int i=0; i<M; i++){
System.out.print(arr[i] + " ");
}
System.out.println();
}
- 1-3) ํ์ฌ i๋ 3์ด๋ค.
์ฌ๊ธฐ์ ์ฐ๋ฆฌ๊ฐ 3์ ๋ฐฉ๋ฌธ ํ ์ ์๋ ์ด์ ๋? ์ฐ๋ฆฌ๋ ์ ์ 1 -> 2-> 3 ์์ผ๋ก ๋ฐฉ๋ฌธ์ ํ๊ธฐ ๋๋ฌธ์ visited[3]=true๋ก ์ค์ ๋์ด ์์ ๊ฒ์ด๋ค.
์ด์ ์ 1->2->3์ ์ข ๋ฃ ํ ๋ค์, ๋ค์ visited[3]์ false๋ก ๋ฐ๊ฟ ์ฃผ์ด์ผ ํ๊ณ ,
๋ค์ 1->2๋ฅผ ์ข ๋ฃ ํ ๋๋, visited[2]๋ฅผ false๋ก ๋ฐ๊ฟ ์ฃผ์ด์ผ ํ๋ค.
์ด๊ฒ์ ์ฝ๋๋ก ๋ํ ๋ด๋ฉด ?
for(int i=1; i<=N; i++) {
arr[index] = i;
visited[i] = true;
recursion(index + 1);
// recursion์ด ๋๋๋ฉด, ์์ ๋
ธ๋๋ฅผ ๋ฐฉ๋ฌธ์ ๋คํ๋ค๋ ์๋ฏธ์ด๋ฏ๋ก ๋ค์ visited[i] = false๋ก ๋ณ๊ฒฝ
visited[i] = false; // * ์ด ๋ถ๋ถ!
}
๊ทธ๋ผ ๋ค์ ์ด์ ๋จ๊ณ๋ก ๋๋์ ๊ฐ๋ฉด,
- 1-3) i = 3์ผ ๋
visited[3] = true๋ก ์ฒดํฌ ํด์ฃผ๊ณ , ๋๊ฒจ ๋ฐ์ index(2)์ i๊ฐ์ธ 3์ ๋ฃ์ด์ค๋ค.
// visited [O,X,O]
for(int i=1; i<=N; i++) {
if(!visited[i]){
visited[i] = true;
arr[index] = i;
recursion(index + 1);
visited[i] = false;
}
}
๊ทธ๋ฆฌ๊ณ ๋ค์ 1,2,3 ๋ ธ๋๋ค์ ๋ฐฉ๋ฌธ์ ํ๊ฒ ๋๋ฉด,
- 1-3-2) visited[1], visited[3] = true;
์ ์ผํ๊ฒ ๋จ์ ๋ ธ๋๋ 2์ด๋ฏ๋ก visited[2] = true, ๋๊ฒจ ๋ฐ์ index์ ํ์ฌ i(2)๊ฐ์ ๋ฃ์ด์ค๋ค.
// visited [O,O,O]
// arr [1,3,2]
// index = 2, M = 3
for(int i=1; i<=N; i++) {
// 1, 3 ๊ฑด๋ ๋. i=2์ผ ๋๋ง ์คํ
if(!visited[2]){
visited[2] = true;
arr[index] = 2;
recursion(index + 1);
visited[2] = false;
}
}
์ฌ๊ธฐ์ recursion(index + 1) -> recursion(3) ์ ํธ์ถํ๊ฒ ๋๋ฉด,
if(index == M){ // index : 3, M : 3
for(int i=0; i<M; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
์ถ๋ ฅ
1 3 2
์ด๋๋ก ๊ณ์ ๋ฐ๋ณตํ๋ฉด ๋๋ค.
์ ์ฒด ์ฝ๋
import java.io.*;
import java.util.StringTokenizer;
public class Main {
static int N, M;
static int[] arr;
static boolean[] isUsed;
static BufferedWriter bw;
public static void main(String[] args) throws IOException {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(bf.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
arr = new int[M+1];
isUsed = new boolean[N+1];
recursion(0);
bw.flush();
bw.close();
}
private static void recursion(int K) throws IOException {
if (K == M) { // ๋ชจ๋ ๋ฐฐ์ด์ ์์๊ฐ ์ฐผ์ ๋,
for (int i = 0; i < M; i++) {
bw.write(arr[i] + " ");
// ๋ง์ฝ ์ฌ๊ธฐ์ ๋ฐฐ์ด์ ๋ค์ด์๋ ๊ฐ์ ๋ฐฉ๋ฌธ์ฌ๋ถ๋ฅผ false๋ก ํด์ฃผ๋๊ฑด? -> ๊ทธ๋ฌ๋ฉด ๋ค์ ๋์๊ฐ์ ๋, ์ค๋ณต์ด ๋์ค๊ฒ ๋๋ค.
// ex) isUsed[arr[i]] = false; ? ์ด๋ป๊ฒ ๋ ๊น?? X
}
bw.write("\n");
return ;
}
for (int i = 1; i <= N; i++) { // [1, ] [2, ] [3, ] ์ด๋ฐ์์ผ๋ก ํธ์ถํ๊ฒ๋
if (!isUsed[i]) { // ์ฌ์ฉ ์ํ์ ๋๋ง, ์คํ
arr[K] = i; // arr[์ธ๋ฑ์ค]์ i๊ฐ์ ๋ฃ์ด์ฃผ๊ณ
isUsed[i] = true; // ๋ฐฉ๋ฌธ ์ฌ๋ถ ํ์!
recursion(K + 1); // ๋ฐฐ์ด์ ๋ค์ ์นธ์ ์ฑ์ฐ๊ธฐ ์ํด์ K๋ฅผ +1ํด์ฃผ๊ณ ๋ค์ ์ฌ๊ท๋ก ๋๋ฆฐ๋ค. K++๋ฅผ ํด์ฃผ๋ฉด ์๋๋ ์ด์ : for๋ฌธ์ ๋๋ ธ์๋, IndexOutOfBoundExcepiton ๋ฐ์ ๊ฐ์ผ!
isUsed[i] = false; // recursion์ด ๋ค ์ํ๋๋ค๋ฉด, ์ถ๋ ฅ๋ ๋๋ฌ๋ค๋ ์๋ฏธ์ด๋, ์ด์ ํด๋น i๊ฐ์ด ์ ์ง๋ ๋, ๋ฐฉ๋ฌธ์ฌ๋ถ๋ฅผ ์์ ์ค๋ค.(์ด์ฐจํผ ํ์ฌ for๋ฌธ์ ์ด์ i๊ฐ์ ์ฌ์ฉ ์ํ๋ค.)
}
}
}
}