백준알고리즘
백준알고리즘: p15649~15652 N과 M(1, 2, 3, 4)
socialcomputer
2021. 4. 8. 23:03
반응형
분류: 백트래킹
처음에 백트래킹도 생소하고 어떻게 접근해야될 지 몰라서 다른 사람들이 어떻게 풀었는지 설명을 좀 찾아봤다.
st-lab.tistory.com/114?category=862595 이 글에서 많이 도움을 받았다.
나중에 잘 모르겠으면 다시 보기... 백트래킹 설명과 dfs와의 차이점 등을 알 수 있었다.
▶문제15649
▶코드
//백준알고리즘 제출시 클래스 이름은 Main으로 바꿔야 됨
package backtracking;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class p15649 {
//1부터 N까지의 수로 M개 짜리 수열 모두 출력해라
public static int[] arr;
public static boolean[] visit;
public static StringBuilder sb = new StringBuilder();
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] s = br.readLine().split(" ");
int N = Integer.parseInt(s[0]);
int M = Integer.parseInt(s[1]);
arr = new int[M];//출력될 수열들
visit = new boolean[N];//인덱스(+1)숫자의 방문여부
dfs(N, M, 0);
System.out.print(sb);
}
public static void dfs(int N, int M, int depth) {
if(depth == M) {
for(int val : arr) {
sb.append(val+" ");
}sb.append("\n");
return;
}
for(int i=0; i<N; i++) {
if(visit[i]==false) {
visit[i] = true;
arr[depth] = i+1;
dfs(N, M, depth+1);
visit[i] = false; //방문하고 나왔으면 다시 false로 바꿔줘야 다른 얘가 방문할 때 들어갈 수 있다.
}
}
}
}
▶재귀호출시 ++대신 +1하기
++ 은 depth 변수의 값 자체가 1 증가하기 때문에 재귀에서 빠져나와도 증가된 값은 그대로 유지되기 떄문
▶arr베열은 출력될 수열이 들어갈 배열이고, visit은 1~N까지의 숫자 중 중복을 거르기 위해 arr배열에 넣어도 되는지 확인하는 용도의 boolean 배열이다.
depth는 깊인데, M과 같아지면 리턴하는 메소드를 위해 있어야 한다. (깊이우선탐색,,)
▶채점결과
▶문제 15650
▶코드
package backtracking;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
//1~N까지 오름차순인 M개의 수열을 출력해라.
public class p15650 {
public static int N;
public static int M;
public static int[] arr;
public static boolean[] visit;
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());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
arr = new int[M];
visit = new boolean[N];
dfs(0, 0);
System.out.print(sb);
}
public static void dfs(int start, int depth) {
if(depth==M) {
for(int val : arr) {
sb.append(val+" ");
}sb.append("\n");
return;
}
for(int i=start; i<N; i++) {//i를 0이 아니라 start부터 돌도록
if( visit[i]==false) {
visit[i] = true;
arr[depth] = i+1;
dfs(i+1,depth+1);//start를 현재 노드의 값+1해줘서 오름차순인 수열만 만들어지도록
visit[i] = false;
}
}
}
}
▶result
▶문제15651
▶코드
package backtracking;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
//수열 중복은 안되지만, 수열 내 중복은 허용.
public class p15651 {
public static int N;
public static int M;
public static int[] arr;
public static boolean[] visit;
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());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
arr = new int[M];
visit = new boolean[N];
dfs(0);
System.out.print(sb);
}
public static void dfs(int depth) {
if(depth==M) {
for(int val : arr) {
sb.append(val+" ");
}sb.append("\n");
return;
}
for(int i=0; i<N; i++) {
visit[i] = true;
arr[depth] = i+1;
dfs(depth+1);
visit[i] = false;
}
}
}
▶채점결과
▶문제15652
▶코드
package backtracking;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class p15652 {
//비내림차순 11 12 13 22 23 33
public static int N;
public static int M;
public static int[] arr;
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());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
arr = new int[M];
dfs(0, 0);
System.out.print(sb);
}
public static void dfs(int start, int depth) {
if(depth==M) {
for(int val : arr) {
sb.append(val+" ");
}sb.append("\n");
return;
}
for(int i=start; i<N; i++) {//중복허용하지만 같거나 크도록 (비내림차순)
arr[depth]=i+1;
dfs(i, depth+1);
}
}
}
▶채점결과
네 문제가 거의 비슷하지만 조금씩 다르게 구현하면 되는 문제였다.
백트래킹에 대해서도 알면서 좋은 공부가 된것 같다.
첫 문제는 블로그에서 보고 시작했지만 다음 문제부턴 내가 풀 수 있었다.
다음에도 이런 문제가 있으면 알아서 해결할 수 있도록 하고싶다.
반응형