CT
[BOJ] 21단계 백트래킹
kinggora
2023. 4. 18. 23:14
백트래킹: 모든 경우를 탐색
| 1 | 15649 | N과 M (1) |
- 1부터 N까지 자연수 중에서 중복 없이 M개를 고른 수열
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
private static int N, M;
private static int[] arr;
private static boolean[] visit;
private static StringBuilder sb = new StringBuilder();
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String[] split = reader.readLine().split(" ");
N = Integer.parseInt(split[0]);
M = Integer.parseInt(split[1]);
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++) {
if(!visit[i]) {
visit[i] = true;
arr[depth] = i + 1;
dfs(depth + 1);
visit[i] = false;
}
}
}
}
*깊이 우선 탐색 DFS
| 2 | 15650 | N과 M (2) |
- 1부터 N까지 자연수 중에서 중복 없이 M개를 고른 수열
- 고른 수열은 오름차순이어야 한다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
private static int N, M;
private static int[] arr;
private static StringBuilder sb = new StringBuilder();
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String[] split = reader.readLine().split(" ");
N = Integer.parseInt(split[0]);
M = Integer.parseInt(split[1]);
arr = new int[M];
dfs(0, 0);
System.out.print(sb);
}
public static void dfs(int depth, int start) {
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(depth + 1, i + 1);
}
}
}
| 3 | 15651 | N과 M (3) |
- 1부터 N까지 자연수 중에서 M개를 고른 수열
- 같은 수를 여러 번 골라도 된다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
private static int N, M;
private static int[] arr;
private static StringBuilder sb = new StringBuilder();
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String[] split = reader.readLine().split(" ");
N = Integer.parseInt(split[0]);
M = Integer.parseInt(split[1]);
arr = new int[M];
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++) {
arr[depth] = i + 1;
dfs(depth + 1);
}
}
}
| 4 | 15652 | N과 M (4) |
- 1부터 N까지 자연수 중에서 M개를 고른 수열
- 같은 수를 여러 번 골라도 된다.
- 고른 수열은 비내림차순이어야 한다.
- 길이가 K인 수열 A가 A1 ≤ A2 ≤ ... ≤ AK-1 ≤ AK를 만족하면, 비내림차순이라고 한다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
private static int N, M;
private static int[] arr;
private static StringBuilder sb = new StringBuilder();
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String[] split = reader.readLine().split(" ");
N = Integer.parseInt(split[0]);
M = Integer.parseInt(split[1]);
arr = new int[M];
dfs(0, 0);
System.out.print(sb);
}
public static void dfs(int depth, int start) {
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(depth + 1, i);
}
}
}
| 5 | 9663 | N-Queen |
| 7 | 14888 | 연산자 끼워넣기 |
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
private static final int[] operator = new int[4];
private static int[] operand;
private static int N;
private static int min = Integer.MAX_VALUE;
private static int max = Integer.MIN_VALUE;
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(reader.readLine());
StringTokenizer tokenizer = new StringTokenizer(reader.readLine());
operand = new int[N];
for(int i = 0; i < N; i++) {
operand[i] = Integer.parseInt(tokenizer.nextToken());
}
tokenizer = new StringTokenizer(reader.readLine());
for(int i = 0; i < 4; i++) {
operator[i] = Integer.parseInt(tokenizer.nextToken());
}
operation(operand[0], 1);
System.out.println(max + "\n" + min);
}
public static void operation(int result, int idx) {
if(idx == N) {
if(result < min) {
min = result;
}
if(result > max) {
max = result;
}
return;
}
for(int i = 0; i < 4; i++) {
if(operator[i] > 0) {
operator[i]--;
switch (i) {
case 0:
operation(result + operand[idx], idx + 1);
break;
case 1:
operation(result - operand[idx], idx + 1);
break;
case 2:
operation(result * operand[idx], idx + 1);
break;
case 3:
operation(result / operand[idx], idx + 1);
break;
}
operator[i]++;
}
}
}
}
| 8 | 14889 | 스타트와 링크 |
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
private static int N;
private static int[][] S;
private static boolean[] team;
private static int min = Integer.MAX_VALUE;
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(reader.readLine());
team = new boolean[N];
S = new int[N][N];
for(int i = 0; i < N; i++) {
StringTokenizer tokenizer = new StringTokenizer(reader.readLine());
for(int j = 0; j < N; j++) {
S[i][j] = Integer.parseInt(tokenizer.nextToken());
}
}
dfs(0, 0);
System.out.println(min);
}
public static void dfs(int depth, int start) {
//start 팀원(N/2명) 선택이 끝나면 나머지 인원은 자동으로 link 팀이 됨
if(depth == N/2) {
int teamStart = 0;
int teamLink = 0;
for(int i = 0; i < N - 1; i++) {
for(int j = i + 1; j < N; j++) {
if(team[i] && team[j]) {
teamStart += S[i][j];
teamStart += S[j][i];
} else if(!team[i] && !team[j]) {
teamLink += S[i][j];
teamLink += S[j][i];
}
}
}
int gap = Math.abs(teamStart - teamLink);
if(gap == 0) {
System.out.println(gap);
System.exit(0);
}
min = Math.min(min, gap);
return;
}
for(int i = start; i < N; i++) {
if(!team[i]) {
team[i] = true;
dfs(depth + 1, i + 1);
team[i] = false;
}
}
}
}